有没有办法在Java中模拟C ++的“朋友”概念?

有没有办法在Java中模拟C ++的“朋友”概念?

我希望能够在一个包中编写一个Java类,它可以访问另一个包中的类的非公共方法,而不必使它成为另一个类的子类。这可能吗?



蝴蝶刀刀
浏览 474回答 3
3回答

三国纷争

Java的设计者明确拒绝了朋友的想法,因为它在C ++中有效。你把你的“朋友”放在同一个包里。私有,受保护和打包的安全性是语言设计的一部分。James Gosling希望Java能够成为C ++而不会出错。我相信他觉得朋友是个错误,因为它违反了OOP原则。包提供了一种合理的方式来组织组件而不会过于纯粹的OOP。NR指出你可以使用反射作弊,但即使只有你没有使用SecurityManager才有效。如果打开Java标准安全性,除非您编写安全策略以明确允许,否则您将无法使用反射作弊。

www说

“朋友”概念在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);     }}
打开App,查看更多内容
随时随地看视频慕课网APP