有没有办法在Java中模拟C ++的“朋友”概念?我希望能够在一个包中编写一个Java类,它可以访问另一个包中的类的非公共方法,而不必使它成为另一个类的子类。这可能吗?
3 回答
三国纷争
TA贡献1804条经验 获得超7个赞
Java的设计者明确拒绝了朋友的想法,因为它在C ++中有效。你把你的“朋友”放在同一个包里。私有,受保护和打包的安全性是语言设计的一部分。
James Gosling希望Java能够成为C ++而不会出错。我相信他觉得朋友是个错误,因为它违反了OOP原则。包提供了一种合理的方式来组织组件而不会过于纯粹的OOP。
NR指出你可以使用反射作弊,但即使只有你没有使用SecurityManager才有效。如果打开Java标准安全性,除非您编写安全策略以明确允许,否则您将无法使用反射作弊。
www说
TA贡献1775条经验 获得超8个赞
“朋友”概念在Java中很有用,例如,将API与其实现分开。实现类通常需要访问API类内部,但这些不应该暴露给API客户端。这可以使用'Friend Accessor'模式实现,详情如下:
通过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);}
来自'friend'实现包中的类的示例访问:
package impl;public final class FriendlyAccessExample { public static void main(String[] args) { Accessor accessor = Accessor.getInstance(); Exposed exposed = accessor.createExposed(); accessor.sayHello(exposed); }}
添加回答
举报
0/150
提交
取消