我希望能够在一个包中编写一个 Java 类,该类可以访问另一个包中类的非公共方法,而不必使其成为另一个类的子类。这可能吗?
“朋友”概念在 Java 中很有用,例如,将 API 与其实现分开。实现类通常需要访问 API 类内部,但这些不应暴露给 API 客户端。这可以使用下面详述的“朋友访问器”模式来实现:
通过 API 暴露的类:
package api; public final class Exposed { static { // Declare classes in the implementation package as 'friends' Accessor.setInstance(new AccessorImpl()); } // Only accessible by 'friend' classes. Exposed() { } // Only accessible by 'friend' classes. void sayHello() { System.out.println("Hello"); } static final class AccessorImpl extends Accessor { protected Exposed createExposed() { return new Exposed(); } protected void sayHello(Exposed exposed) { exposed.sayHello(); } } }
提供“朋友”功能的类:
package impl; public abstract class Accessor { private static Accessor instance; static Accessor getInstance() { Accessor a = instance; if (a != null) { return a; } return createInstance(); } private static Accessor createInstance() { try { Class.forName(Exposed.class.getName(), true, Exposed.class.getClassLoader()); } catch (ClassNotFoundException e) { throw new IllegalStateException(e); } return instance; } public static void setInstance(Accessor accessor) { if (instance != null) { throw new IllegalStateException( "Accessor instance already set"); } instance = accessor; } protected abstract Exposed createExposed(); protected abstract void sayHello(Exposed exposed); }
从“朋友”实现包中的类访问示例:
package impl; public final class FriendlyAccessExample { public static void main(String[] args) { Accessor accessor = Accessor.getInstance(); Exposed exposed = accessor.createExposed(); accessor.sayHello(exposed); } }