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


当前回答

我更喜欢委托、组合或工厂类(取决于导致这个问题的问题),以避免将其设置为公共类。

如果是“不同包中的接口/实现类”问题,那么我将使用一个公共工厂类,它将与impl包位于同一个包中,并防止impl类的暴露。

如果这是一个“我讨厌让这个类/方法公开,只是为了在不同的包中为其他类提供这个功能”的问题,那么我会在同一个包中使用一个公共委托类,并且只公开“外部”类所需的部分功能。

其中一些决策是由目标服务器类加载体系结构(OSGi包、WAR/EAR等)、部署和包命名约定驱动的。例如,上面提出的解决方案“朋友访问器”模式对于普通的java应用程序非常聪明。我想知道在OSGi中实现它是否会因为类加载风格的不同而变得棘手。

其他回答

没有使用关键字左右。

你可以使用反射等“作弊”,但我不建议“作弊”。

据我所知,这是不可能的。

也许,你可以给我们更多关于你的设计的细节。像这样的问题很可能是设计缺陷造成的。

只考虑

如果这些类如此密切相关,为什么它们在不同的包中? A是否访问B的私有成员,或者操作是否应该移动到类B并由A触发? 这是真正的调用还是事件处理更好?

我同意在大多数情况下,friend关键字是不必要的。

包的私有(又名。默认值)在大多数情况下(您有一组严重交织的类)就足够了 对于希望访问内部内容的调试类,我通常将方法设置为私有并通过反射访问它。速度在这里通常不重要 有时,您实现的方法是“黑客”或其他容易更改的方法。我将其设为public,但使用@Deprecated表示不应该依赖于此方法。

最后,如果确实有必要,还有其他答案中提到的朋友访问器模式。

我认为c++中的友类就像Java中的内部类概念。使用内部类 实际上可以定义一个外围类和一个封闭类。封闭类具有对其封闭类的public和private成员的完全访问权。 请看下面的链接: http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html

我曾经见过一个基于反射的解决方案,它在运行时使用反射进行“好友检查”,并检查调用堆栈,以查看调用该方法的类是否允许这样做。作为运行时检查,它有一个明显的缺点。