2015-04-15 12 views
6

Mam dwie klasy:z innej klasy w Javie

public class Class1{} 
public class Class2{ 
    private void simpleMethod(){ /*...*/ } 
} 

W Class2 mam metodę prywatną simpleMethod() i chcę go używać w Class1 w tym samym projekcie. Nie chcę zmienić nazwy tej metody na public, ponieważ nie chcę jej wyświetlać w moim interfejsie API. Czy mogę utworzyć metodę public bez wyświetlania jej w interfejsie API? Albo coś innego?

Odpowiedz

8

Jeśli obie klasy znajdują się w tym samym pakiecie, można pozostawić domyślną widoczność simpleMethod, więc może ona być używana tylko przez klasę i klasy w tym samym pakiecie.

package org.foo; 
public class Class1 { 
    //visibility for classes in the same package 
    void simpleMethod() { } 
} 

package org.foo; 
public class Class2 { 
    public void anotherMethod() { 
     Class1 class1 = new Class(); 
     class1.simpleMethod(); //compiles and works 
    } 
} 

package org.bar; 
import org.foo.Class1; 
public class Class3 { 
    public void yetAnotherMethod() { 
     Class1 class1 = new Class1(); 
     class1.simpleMethod(); //compiler error thrown 
    } 
} 
13

Jeśli Class1 i Class2 są zarówno w tym samym opakowaniu można po prostu usunąć modyfikator private, co czyni metodę package-private. W ten sposób nie zostanie ujawniony w interfejsie API, a będziesz mieć do niego dostęp od Class1.

Przed:

public class Class2 { 
    // method is private 
    private void simpleMethod() { ... } 
} 

Po:

public class Class2 { 
    // method is package-private: can be accessed by other classes in the same package 
    void simpleMethod() { ... } 
} 
1

Oprócz powyższego scenariusza, można użyć refleksji API do dostępu metodę prywatną, jak poniżej:

Class a = Class.forName(""); 
Method method = a.getDeclaredMethods()[0];//retrieve your method here 
method.setAccessible(true); 
+0

Korzystanie z odbicia # setAccessible (true) powinno być zdecydowanie uzasadnione. – Ernusc

3

Well, inna droga byłoby mieć dwa różne interfejsy. Jeden dla twojego publicznego API i jeden dla twojego wewnętrznego API, twój obiekt z Class2 zaimplementowałby oba. Każdy, kto zajmuje się API będzie rozmawiać z nią za pośrednictwem interfejsu publicznego jesteś narażony

public class Class2 implements PublicApi2 { 
    public void somePrivateMethod() { 
     ... 
    } 

    @Override 
    public void somePublicMethod() { 
     ... 
    } 

} 

(nie realizować dwa interfejsy w tutaj, jak sprawa rzeczywistości nie ma potrzeby na „prywatny”, ponieważ jeden obiektów twojej biblioteki/frameworku/czymkolwiek, co może zająć się konkretnymi klasami, ale to zależy od ciebie)

Klienci zawsze będą odnosić się do twojego obiektu jako typu "PublicApi2" i nigdy nie zajmą się konkretną realizacją (Class2), wewnętrzne zdania.