有没有办法在Java中模拟C++“朋友”概念?
我希望能够在一个包中编写一个Java类,该包可以访问另一个包中某个类的非公共方法,而不必使其成为另一个类的子类。这可能吗?
我希望能够在一个包中编写一个Java类,该包可以访问另一个包中某个类的非公共方法,而不必使其成为另一个类的子类。这可能吗?
这是我在JAVA中使用的一个小技巧,用于复制C++朋友机制。
假设我有一个类和另一个类。出于仇恨的原因,他们处于不同的包装(家庭)中。Romeo
Juliet
Romeo
想,只想让她。cuddle
Juliet
Juliet
Romeo
cuddle
在C++,会声明为(情人),但在java中没有这样的东西。Juliet
Romeo
friend
以下是类和技巧:
女士优先 :
package capulet;
import montague.Romeo;
public class Juliet {
public static void cuddle(Romeo.Love love) {
Objects.requireNonNull(love);
System.out.println("O Romeo, Romeo, wherefore art thou Romeo?");
}
}
所以方法是,但你需要一个来调用它。它将其用作“签名安全性”,以确保只能调用此方法并检查爱是真实的,以便运行时将抛出一个如果它是.Juliet.cuddle
public
Romeo.Love
Romeo.Love
Romeo
NullPointerException
null
现在男孩 :
package montague;
import capulet.Juliet;
public class Romeo {
public static final class Love { private Love() {} }
private static final Love love = new Love();
public static void cuddleJuliet() {
Juliet.cuddle(love);
}
}
该类是公共的,但其构造函数是 。因此,任何人都可以看到它,但只能构建它。我使用静态引用,因此从未使用过的引用只构造一次,并且不会影响优化。Romeo.Love
private
Romeo
Romeo.Love
因此,可以而且只有他可以,因为只有他可以构造和访问一个实例,这是她所要求的(否则她会用一个打你)。Romeo
cuddle
Juliet
Romeo.Love
Juliet
cuddle
NullPointerException
Java的设计者明确拒绝了朋友的想法,因为它在C++中工作。你把你的“朋友”放在同一个包装里。私有、受保护和打包的安全性作为语言设计的一部分强制实施。
James Gosling 希望 Java 能够C++,而不会出错。我相信他觉得朋友是一个错误,因为它违反了OOP原则。包提供了一种合理的方法来组织组件,而不必过于纯粹地对待OOP。
NR指出,你可以使用反射来作弊,但即使这样,也只有在你不使用SecurityManager时才有效。如果打开 Java 标准安全性,则无法通过反射进行作弊,除非您编写安全策略来明确允许它。