Java 作为公共方法返回类型的私有类
为什么这是有效的 Foo.javaJava 作为公共方法返回类型的私有类,java,polymorphism,access-modifiers,Java,Polymorphism,Access Modifiers,为什么这是有效的 Foo.java public class Foo { public Bar getBar() { return new Bar(); } private class Bar {} } 如果Bar是私有的,这个类的用户将如何使用这个方法?当然可以使用多态性,但这不应该是无效的,并且声明应该将其指示为返回一个对象吗 public class Foo { private String myString; publi
public class Foo {
public Bar getBar() {
return new Bar();
}
private class Bar {}
}
如果Bar是私有的,这个类的用户将如何使用这个方法?当然可以使用多态性,但这不应该是无效的,并且声明应该将其指示为返回一个对象吗
public class Foo {
private String myString;
public String getMyString() {
return myString;
}
}
这也是有效的。为什么内部类的行为应该不同
将条设置为私有
只会使外部世界看不到它,就像将字段设置为私有
一样
一个重要的警告是,即使能够对Foo
对象调用getBar()
,也不能调用该引用的方法(因为可见性)
所以最重要的是你可以这样做,但是你不应该这样做
我能想象的唯一情况是,
Foo
也是一个内部类,Foo
的外部类想要使用Bar它是有效的,因为Bar
对Foo
类可见。它就是这样编译的
当然,另一个类不能看到条
,因此不能使用返回值
public class FooBar {
public void invokeBar() {
Foo foo = new Foo();
foo.getBar();
}
}
但是另一个类仍然可以在不使用返回值的情况下调用该方法
public class FooBar {
public void invokeBar() {
Foo foo = new Foo();
foo.getBar();
}
}
内部类
内部类表示一种特殊类型的关系,即它可以访问外部类(包括private)的所有成员(数据成员和方法)。嵌套类可以产生更可读和可维护的代码,因为它只在一个地方对类进行逻辑分组
为什么这是有效的
因为调用位置中的客户端代码可能需要一个对象(或者根本不需要任何对象),所以从任何地方调用此方法都没有问题:
Object o = new Foo().getBar();
如果您需要能够从任何范围调用该方法(例如,改变Foo的内部状态),并且如果您除了简单地调用该方法之外还需要任何类型的结果,那么返回私有类的公共方法可能非常有用。它是嵌套类型的一种形式。这种类声明称为内部类。如果您将内部类声明为静态类,那么它将被称为顶级嵌套类。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
类(它是内部类)之间的关系。一个账户
类可以有多个交易
对象,但是没有账户
对象,交易对象就不能存在
尽管如此,返回私有内部类的对象是无用的,因为它在其类之外变得不可见。如上面的账户
和交易
类示例所述<代码>交易
如果没有账户
对象就不可能存在。我刚刚对此做了一些研究,还没有找到明确的答案。很可能这只是Java语言设计者的一个疏忽,因为它实际上并没有造成任何伤害,所以它被保留了下来。这与将public
方法放入private
类没有什么区别。没有任何东西可以阻止您这样做,即使无法实际访问该public
方法
当然,当您尝试这样做时,NetBeans会向您发出警告“通过公共API导出非公共类型”。我希望大多数其他环境都会给出类似的警告
返回的对象对于任何试图使用它的人来说都是完全无用的(除非他们使用反射),他们所能做的几乎就是将其存储到对象中(或他们确实有权访问的任何其他超类),然后将该对象传递给其他人
如果传递的对象
被用作传递但从未操作的“句柄”,则可能需要执行此操作。在这种情况下,让类public
更有意义,但是要让类中的所有方法private
防止它们在类之外被操作(或者定义一个public
接口返回并让private
类实现它)
所以答案似乎是:
它可能不应该是有效的,但因为它不会造成任何伤害,所以从未被阻止
关于类似的问题,这里有一个很好的答案:
我有一个非常有效的用例,我很高兴这是允许的
让我们留下来吧,你有一个创建UI片段的类。它接受某种域对象并创建一个UI:
public Node createPersonUI(Person person) {
BasePanel panel = new BasePanel();
// ... setup panel with values ...
return panel;
}
BasePanel
是Node
的一个子类,是调用者与之无关的某个内部类,因为该类决定事情的外观
现在,当我需要支持时,我发现自己需要重新使用这个类的一部分
public Node createPersonalProfileUI(PersonalProfile profile) {
BasePanel panel = (BasePanel)createPerson(profile.getPerson());
// ... only setup missing values ...
return panel;
}
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 {
}