2009-12-27 12 views
108

मेरे पास मेरे प्रोजेक्ट में दो पैकेज हैं: odp.proj और odp.proj.test। कुछ विधियां हैं जिन्हें मैं केवल इन दो पैकेजों में कक्षाओं में दिखाना चाहता हूं। मैं यह कैसे कर सकता हूँ?जावा: उप-दृश्य दृश्यता?

संपादित करें: अगर वहाँ जावा में किसी सबपैकेज की धारणा नहीं है, इसलिए इस के आसपास किसी भी तरह है? मेरे पास कुछ विधियां हैं जिन्हें मैं केवल टेस्टर्स और उस पैकेज के अन्य सदस्यों के लिए उपलब्ध होना चाहता हूं। क्या मुझे बस एक ही पैकेज में सब कुछ फेंक देना चाहिए? व्यापक प्रतिबिंब का प्रयोग करें?

+0

http://stackoverflow.com/questions/2388253/separation-of-junit-classes-into-special-test-package – Abdull

+0

http://stackoverflow.com/questions/13809713/java-package-in-package –

+1

एक तरफ के रूप में, परीक्षणों को केवल पैकेज के बाहर से देखने योग्य आपकी ऑब्जेक्ट्स के * व्यवहार * का परीक्षण करना चाहिए। अपने परीक्षणों से पैकेज-स्कोप विधियों/कक्षाओं तक पहुंचने से मुझे पता चलता है कि परीक्षण शायद कार्यान्वयन का परीक्षण नहीं कर रहे हैं। मेवेन या ग्रेडल जैसे निर्माण उपकरण का उपयोग करके, वे आपके परीक्षणों को उसी कक्षा में चलाने के लिए आसान बना देंगे लेकिन अंतिम जार (एक अच्छी बात) में शामिल नहीं किया जाएगा, इस प्रकार उनके पास अलग-अलग पैकेज नाम होने की आवश्यकता नहीं है। फिर भी उन्हें अलग-अलग पैकेजों में डाल देना * यह लागू करना है कि आप निजी/डिफ़ॉल्ट दायरे तक नहीं पहुंचते हैं * और इस प्रकार केवल सार्वजनिक एपीआई का परीक्षण करते हैं। – derekv

उत्तर

126

आप नहीं कर सकते। जावा में उप-पैकेज की कोई अवधारणा नहीं है, इसलिए odp.proj और odp.proj.test पूरी तरह अलग पैकेज हैं।

+3

हालांकि मुझे यह पसंद है, यह भ्रमित है कि अधिकांश आईडीई एक ही नाम के साथ संकुल डालते हैं। स्पष्टीकरण के लिए धन्यवाद। – JacksOnF1re

11

यह odp.proj और odp.proj.test के बीच कोई विशेष संबंध नहीं है - वे बस स्पष्ट रूप से संबंधित नाम के रूप में नामित होते हैं।

यदि odp.proj.test पैकेज केवल परीक्षण प्रदान कर रहा है तो आप उसी पैकेज नाम (odp.proj) का उपयोग कर सकते हैं। ग्रहण और नेटबीन्स जैसे आईडीई अलग पैकेजर्स (src/main/java/odp/proj और src/test/java/odp/proj) उसी पैकेज नाम के साथ बनाएंगे लेकिन जुनीट सेमेन्टिक्स के साथ।

ध्यान दें कि ये आईडीई odp.proj में विधियों के लिए परीक्षण उत्पन्न करेंगे और परीक्षण विधियों के लिए उचित फ़ोल्डर बनायेगा जो मौजूद नहीं है।

50

आपके पैकेज के नाम संकेत देते हैं कि यहां आवेदन इकाई परीक्षण के लिए है। उपयोग किया जाने वाला सामान्य पैटर्न उन वर्गों को रखना है जिन्हें आप परीक्षण करना चाहते हैं और उसी पैकेज में इकाई परीक्षण कोड (आपके मामले में odp.proj) लेकिन विभिन्न स्रोत पेड़ों में। तो आप अपनी कक्षाओं को src/odp/proj और test/odp/proj में अपना टेस्ट कोड डाल देंगे।

जावा में "पैकेज" एक्सेस संशोधक है जो डिफ़ॉल्ट एक्सेस संशोधक है जब कोई निर्दिष्ट नहीं किया जाता है (यानी आप सार्वजनिक, निजी या संरक्षित निर्दिष्ट नहीं करते हैं)। "पैकेज" एक्सेस संशोधक के साथ, केवल odp.proj में कक्षाओं के पास विधियों तक पहुंच होगी। लेकिन ध्यान रखें कि जावा में, एक्सेस संशोधकों को एक्सेस नियमों को लागू करने के लिए भरोसा नहीं किया जा सकता है क्योंकि प्रतिबिंब के साथ, कोई भी एक्सेस संभव है। एक्सेस संशोधक केवल सूचक हैं (जब तक कि एक प्रतिबंधित सुरक्षा प्रबंधक मौजूद न हो)।

0

विधि के सामने पहुंच संशोधक डालने के बिना आप कहते हैं कि यह पैकेज निजी है।
निम्नलिखित उदाहरण देखें।

package odp.proj; 
public class A 
{ 
    void launchA() { } 
} 

package odp.proj.test; 
public class B 
{ 
    void launchB() { } 
} 

public class Test 
{ 
    public void test() 
    { 
     A a = new A(); 
     a.launchA() // cannot call launchA because it is not visible 
    } 
} 
1

संपादित करें: अगर जावा में एक सबपैकेज की धारणा नहीं है, वहाँ किसी भी तरह से इस के आसपास है? मेरे पास कुछ विधियां है जो मैं केवल परीक्षकों और पैकेज के अन्य सदस्यों के लिए उपलब्ध होना चाहता हूं।

यह शायद उन्हें प्रदर्शित नहीं करने के लिए अपने इरादों पर थोड़ा निर्भर करता है, लेकिन अगर एकमात्र कारण है कि आप (या कुछ अन्य आंतरिक बात) केवल परीक्षण के लिए इरादा चीजों के साथ सार्वजनिक इंटरफ़ेस अपवित्र नहीं करना चाहती है मैं विधियों को एक अलग सार्वजनिक इंटरफ़ेस में रखेगा और "छिपा" विधियों के उपभोक्ता उस इंटरफ़ेस का उपयोग करेंगे। यह दूसरों को इंटरफ़ेस का उपयोग करने से नहीं रोकेगा, लेकिन मुझे कोई कारण नहीं दिख रहा है कि आपको क्यों करना चाहिए।

यूनिट परीक्षणों के लिए, और यदि यह बहुत कुछ लिखने के बिना संभव है, तो उसी पैकेज का उपयोग करने के लिए सुझावों का पालन करें।

5

जब मैं IntelliJ में ऐसा करते हैं, मेरे स्रोत पेड़ इस तरह दिखता है:

src   // source root 
- odp 
    - proj // .java source here 
- test  // test root 
    - odp 
    - proj // JUnit or TestNG source here 
0
PackageVisibleHelper वर्ग के साथ

, और कहीं भी में पहले PackageVisibleHelperFactory जमे हुए, हम launchA (PackageVisibleHelper द्वारा) आह्वान कर सकते हैं इसे निजी रखें विधि :)

package odp.proj; 
public class A 
{ 
    void launchA() { } 
} 

public class PackageVisibleHelper { 

    private final PackageVisibleHelperFactory factory; 

    public PackageVisibleHelper(PackageVisibleHelperFactory factory) { 
     super(); 
     this.factory = factory; 
    } 

    public void launchA(A a) { 
     if (factory == PackageVisibleHelperFactory.INSTNACNE && !factory.isSampleHelper(this)) { 
      throw new IllegalAccessError("wrong PackageVisibleHelper "); 
     } 
     a.launchA(); 
    } 
} 


public class PackageVisibleHelperFactory { 

    public static final PackageVisibleHelperFactory INSTNACNE = new PackageVisibleHelperFactory(); 

    private static final PackageVisibleHelper HELPER = new PackageVisibleHelper(INSTNACNE); 

    private PackageVisibleHelperFactory() { 
     super(); 
    } 

    private boolean frozened; 

    public PackageVisibleHelper getHelperBeforeFrozen() { 
     if (frozened) { 
      throw new IllegalAccessError("please invoke before frozen!"); 
     } 
     return HELPER; 
    } 

    public void frozen() { 
     frozened = true; 
    } 

    public boolean isSampleHelper(PackageVisibleHelper helper) { 
     return HELPER.equals(helper); 
    } 
} 
package odp.proj.test; 

import odp.proj.A; 
import odp.proj.PackageVisibleHelper; 
import odp.proj.PackageVisibleHelperFactory; 

public class Test { 

    public static void main(String[] args) { 

     final PackageVisibleHelper helper = PackageVisibleHelperFactory.INSTNACNE.getHelperBeforeFrozen(); 
     PackageVisibleHelperFactory.INSTNACNE.frozen(); 


     A a = new A(); 
     helper.launchA(a); 

     // illegal access  
     new PackageVisibleHelper(PackageVisibleHelperFactory.INSTNACNE).launchA(a); 
    } 
} 
0

दूसरों के रूप में समझा दिया है, वहाँ एक "सबपैकेज" जावा में जैसी कोई चीज नहीं है: सभी संकुल अलग कर रहे हैं और अपने माता-पिता से कुछ भी नहीं प्राप्त करती हैं।

किसी अन्य पैकेज से संरक्षित वर्ग के सदस्यों तक पहुंचने का एक आसान तरीका कक्षा का विस्तार करना और सदस्यों को ओवरराइड करना है।

उदाहरण के लिए, पैकेज a.b में ClassInA तक पहुँचने के लिए:

package a.b; 

import a.ClassInA; 

public class ClassInAInB extends ClassInA{ 
    ClassInAInB(String data){ super(data); } 

    @Override 
    protected byte[] getDataAsBytes(){ return super.getDataAsBytes(); } 
} 

आप अधिभावी वर्ग का उपयोग करने देता है कि:

package a; 

public class ClassInA{ 
    private final String data; 

    public ClassInA(String data){ this.data = data; } 

    public String getData(){ return data; } 

    protected byte[] getDataAsBytes(){ return data.getBytes(); } 

    protected char[] getDataAsChars(){ return data.toCharArray(); } 
} 

कि पैकेज है कि तरीकों को ओवरराइड करता है में एक वर्ग आप ClassInA में की जरूरत बनाने के अन्य पैकेज में कक्षा के स्थान पर:

package a.b; 

import java.util.Arrays; 

import a.ClassInA; 

public class Driver{ 
    public static void main(String[] args){ 
     ClassInA classInA = new ClassInA("string"); 
     System.out.println(classInA.getData()); 
     // Will fail: getDataAsBytes() has protected access in a.ClassInA 
     System.out.println(Arrays.toString(classInA.getDataAsBytes())); 

     ClassInAInB classInAInB = new ClassInAInB("string"); 
     System.out.println(classInAInB.getData()); 
     // Works: getDataAsBytes() is now accessible 
     System.out.println(Arrays.toString(classInAInB.getDataAsBytes())); 
    } 
} 

ध्यान दें कि यह केवल संरक्षित सदस्यों के लिए काम करता है, जो कक्षाओं को विस्तारित करने के लिए दृश्यमान हैं, न कि पैकेज-निजी सदस्य, जो नहीं हैं। उम्मीद है कि यह किसी की मदद करता है!

संबंधित मुद्दे