为什么这有效?
Foo.java
public class Foo {
public Bar getBar() {
return new Bar();
}
private class Bar {}
}
如果Bar是私有的,这个类的用户将如何使用此方法?当然可以使用多态,但是这不应该是无效的,并且声明应该指出这是返回一个对象吗?
答案 0 :(得分:9)
我刚刚对此进行了一些研究,但未能找到明确的答案。它似乎很可能只是Java语言设计者的疏忽,因为它实际上并没有造成任何伤害。将public
方法放入private
类并没有什么不同。即使没有办法真正访问public
方法,也没有什么能阻止你这样做。
当您尝试执行此操作时,NetBeans当然会向您发出警告“通过公共API导出非公共类型”。我希望大多数其他环境会发出类似的警告。
对于尝试使用它的人来说,返回的对象完全没用(除非他们使用反射),他们几乎所能做的就是将它存储到Object
(或者他们有权访问的任何其他超类中) to)然后传递Object
。
如果传递的Object
被用作传递但从未操作的“句柄”,则可能希望这样做。在这种情况下,虽然让课程public
更有意义,但要在其中private
制作所有方法,以防止它们在课堂外作用(或定义public
返回的接口,让private
类实现该。)。
所以答案似乎是:
它可能不应该有效,但因为它没有造成任何伤害,所以它从未被阻止过。
对于类似的主题,这里有一个很好的答案:
答案 1 :(得分:3)
为什么这有效?
因为调用地点的客户端代码可能期望Object
(或根本不期待任何事情),所以从任何地方调用此方法都没有问题:
Object o = new Foo().getBar();
答案 2 :(得分:1)
public class Foo {
private String myString;
public String getMyString() {
return myString;
}
}
这也是有效的。内部类为什么表现不同?
制作Bar
private
只会让外部世界看不到它,就像制作字段private
一样。
一个重要的警告是,即使您能够在getBar()
对象上调用Foo
,也无法调用该引用的方法(因为可见性)。
所以主要的是你可以这样做,但你不应该这样做。
我能想象的唯一情况是Foo
也是一个内部类,Foo
的外部类想要使用Bar
。
答案 3 :(得分:1)
这是有效的,因为Bar
类可以看到Foo
。因此它编译。</ p>
当然另一个班级看不到Bar
,因此无法使用返回值。
但是另一个类仍然可以在不使用返回值的情况下调用该方法。
public class FooBar {
public void invokeBar() {
Foo foo = new Foo();
foo.getBar();
}
}
答案 4 :(得分:1)
返回私有类的公共方法可能很有用,您需要能够从任何范围调用该方法(例如,改变Foo的内部状态),如果您需要任何类型的结果,则需要内部使用简单地调用方法。
答案 5 :(得分:0)
内部课程
内部类表示一种特殊类型的关系,它可以访问外部类的所有成员(数据成员和方法),包括private。嵌套类可以使代码更具可读性和可维护性,因为它只在一个地方对类进行逻辑分组。
答案 6 :(得分:0)
它是嵌套类型的一种形式。这种类声明称为内部类。如果将内部类声明为static,那么它将被称为顶级嵌套类。 Java中可用的其他形式的嵌套类型是本地类;在块中声明和定义的类,即方法或构造函数或初始化块。嵌套类型的第四种形式是匿名类;没有任何名称的类,其对象用于定义类的位置。
就您的情况而言,即内部类,可以使用公共,私有和受保护的访问说明符声明类中的所有类。封闭类中的所有类以及封闭类本身都共享信任关系。这意味着,内部类的所有私有成员以及封闭类的私有成员彼此共享。但是,如果没有封闭类的对象,则无法访问内部类的对象。
当您尝试创建内部类编译器的对象时,将报告编译时错误。但是下面的示例访问每个其他类的私有成员,即封闭类访问私有成员的内部类和内部类访问私有成员的封闭类:
class Bar {
private static int x;
public void getFoo() {
System.out.println(new Foo().y);
}
private class Foo {
private int y;
public void getBar() {
System.out.println(Bar.x);
}
}
}
public class Test{
public static void main(String[] a) {
Bar b = new Bar();
//Bar.Foo f = new Bar.Foo(); This is completely illegal syntax.
}
}
内部类的最佳示例是封闭类的Accounts
类与内部类的Transaction
类的关系。一个Accounts
类可以有多个Transaction
对象,但没有Accounts
对象,Transaction对象不能存在。
虽然,返回私有内部类的对象是无用的,因为它在类之外变得不可见。正如Accounts
和Transaction
类的上述示例所述。没有Transaction
对象,Accounts
不能存在。
答案 7 :(得分:0)
我有一个非常有效的用例,很高兴这被允许。
让我们留下一个创建UI片段的类。它接受某种域对象并创建一个UI:
public Node createPersonUI(Person person) {
BasePanel panel = new BasePanel();
// ... setup panel with values ...
return panel;
}
BasePanel
是Node
的子类,并且是与调用者无关的一些内部类,因为此类确定了外观。
现在,当我需要支持一个新对象PersonalProfile
时,我需要重用该类的一部分,该对象不仅包含更多信息,而且还包含基本的Person
数据:< / p>
public Node createPersonalProfileUI(PersonalProfile profile) {
BasePanel panel = new BasePanel();
// ... setup panel with values ...
return panel;
}
但是,该代码被部分复制了,所以我做到了:
public Node createPersonalProfileUI(PersonalProfile profile) {
BasePanel panel = (BasePanel)createPerson(profile.getPerson());
// ... only setup missing values ...
return panel;
}
但是强制转换有点荒谬-将其更改为返回BasePanel
不仅有效,而且不会暴露我的私有类的任何功能。相反,它只公开其继承自...的所有公共类中的方法!
完整代码:
public BasePanel createPersonUI(Person person) {
BasePanel panel = new BasePanel();
// ... setup panel with values ...
return panel;
}
public BasePanel createPersonalProfileUI(PersonalProfile profile) {
BasePanel panel = createPerson(profile.getPerson());
// ... only setup missing values ...
return panel;
}
private class BasePanel extends Node {
}