我是Java新手.我想知道在私有类中使用公共构造函数是什么.类中的私有类可以从同一个类初始化然后将私有类的构造函数公开的用途是什么?
public class MainActivity extends Activity {
private class AcceptThread extends Thread {
public AcceptThread() {
}
}
}
Run Code Online (Sandbox Code Playgroud)
kap*_*pex 15
对于具有私有类的公共或受保护修饰符,似乎没有任何实际用例.如果您在单个文件中有多个类(但不是嵌套或本地),则需要非私有构造函数来实例化私有类.
// X.java
public class X {
private Y y = new Y();
}
class Y {
Y () {
// if this were private, X wouldn't be able to create an instance of Y
}
}
Run Code Online (Sandbox Code Playgroud)
实际上,默认或protected可见性足以在这种情况下创建实例.所有非私有修饰符都允许您从同一个包中的其他类创建实例,但实际上具有相同的可见性.
public这里没有使用方法.protected也没有用.IllegalAccessException.它首先检查类可见性,然后检查成员可见性.该默认修饰符是最严格的修改,允许你直接调用其他类的构造函数,所以包私人似乎是构造最合适的知名度以及任何其他非私有方法.这样做的另一个好处是,如果将来更改类可见性,则不会意外地将构造函数或任何方法公开给公众.
小智 7
你知道,我几乎每次创建私人内部课时都会问自己这个问题,但我总是认为公共构造函数可能有一些(可能是人为的)理由.所以@kapep的回答让我感到刺痛,并鼓励他们找到一种方法来要求私人内部类的公共构造函数,但我想的越多,并且试验它越多,我认为漏洞就越多.
可能的角度,所有这些都让我失望:
序列化:当解组一个超类不可序列化的对象时,超类需要一个可从子类访问的无参数构造函数.所以,protected这里应该总是足够的.
反射工具:使用反射通过返回的实例获取内部类构造函数的代码.失败,因为首先检查类型可见性,正如@kapep指出的那样,尽管它留下了一个相当有趣的错误消息:
线程"main"中的异常java.lang.IllegalAccessException:类A无法访问类contrived.B $ C的成员,修饰符为"public"
内部阶级延伸shenanigans:不要在家里尝试:
package a;
class Outer {
private class Inner {
}
}
package b;
// compile error: Outer.Inner has private access in Outer
class Extender extends a.Outer.Inner {
Extender(a.Outer outer) {
outer.super();
}
}
Run Code Online (Sandbox Code Playgroud)
起初似乎很有希望,但我对这一点并没有太过分.
最后,我找不到一种方法来使私有内部类的公共构造函数有用.
那为什么这在技术上是合法的,尽管没有用?可能是因为当没有提供其他构造函数时,编译器会自动插入一个无参数的公共构造函数.因此,语言不应该禁止这种结构.不过,更多的是人工制品而不是理由.