Java中内部类和静态嵌套类的主要区别是什么?设计/实现是否在选择其中一个方面发挥作用?
当前回答
A图表
静态嵌套类和非静态嵌套类之间的主要区别在于,静态嵌套类不能访问非静态外部类成员
其他回答
不同之处在于,同样是静态的嵌套类声明可以在封闭类之外实例化。
当您有一个非静态的嵌套类声明(也称为内部类)时,Java不允许您实例化它,除非通过封闭类。从内部类创建的对象链接到从外部类创建的目标,因此内部类可以引用外部类的字段。
但是如果它是静态的,那么链接就不存在,外部字段就不能被访问(除非像其他对象一样通过普通引用),因此您可以自己实例化嵌套类。
当我们在类中声明静态成员类时,它被称为顶级嵌套类或静态嵌套类。可以证明如下:
class Test{
private static int x = 1;
static class A{
private static int y = 2;
public static int getZ(){
return B.z+x;
}
}
static class B{
private static int z = 3;
public static int getY(){
return A.y;
}
}
}
class TestDemo{
public static void main(String[] args){
Test t = new Test();
System.out.println(Test.A.getZ());
System.out.println(Test.B.getY());
}
}
当我们在类中声明非静态成员类时,它被称为内部类。内部类可演示如下:
class Test{
private int i = 10;
class A{
private int i =20;
void display(){
int i = 30;
System.out.println(i);
System.out.println(this.i);
System.out.println(Test.this.i);
}
}
}
嵌套静态类的使用有一个微妙之处,这在某些情况下可能很有用。
尽管静态属性在类通过其构造函数实例化之前被实例化,嵌套静态类内部的静态属性似乎在类的构造函数被调用,或者至少直到属性被首次引用之后,即使它们被标记为“最终”。
考虑以下示例:
public class C0 {
static C0 instance = null;
// Uncomment the following line and a null pointer exception will be
// generated before anything gets printed.
//public static final String outerItem = instance.makeString(98.6);
public C0() {
instance = this;
}
public String makeString(int i) {
return ((new Integer(i)).toString());
}
public String makeString(double d) {
return ((new Double(d)).toString());
}
public static final class nested {
public static final String innerItem = instance.makeString(42);
}
static public void main(String[] argv) {
System.out.println("start");
// Comment out this line and a null pointer exception will be
// generated after "start" prints and before the following
// try/catch block even gets entered.
new C0();
try {
System.out.println("retrieve item: " + nested.innerItem);
}
catch (Exception e) {
System.out.println("failed to retrieve item: " + e.toString());
}
System.out.println("finish");
}
}
即使“nested”和“innerItem”都声明为“static final”。设置nested.innerItem的值在类实例化后才会发生(或至少直到第一次引用嵌套的静态项之后),正如您自己所看到的通过注释和取消注释上面提到的行。这一点不成立对于“outerItem”为true。
至少这是我在Java6.0中看到的。
嵌套类是一个非常通用的术语:每个不是顶级的类都是嵌套类。内部类是非静态嵌套类。约瑟夫·达西写了一篇关于嵌套、内部、成员和顶级课程的非常好的解释。
从Java教程:
嵌套类分为两类:静态类和非静态类。声明为静态的嵌套类简单地称为静态嵌套类。非静态嵌套类称为内部类。
使用封闭类名访问静态嵌套类:
OuterClass.StaticNestedClass
例如,要为静态嵌套类创建对象,请使用以下语法:
OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
作为内部类实例的对象存在于外部类的实例中。考虑以下类别:
class OuterClass {
...
class InnerClass {
...
}
}
InnerClass实例只能存在于OuterClass实例中,并且可以直接访问其封闭实例的方法和字段。
要实例化内部类,必须首先实例化外部类。然后,使用以下语法在外部对象中创建内部对象:
OuterClass outerObject = new OuterClass()
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
请参见:Java教程-嵌套类
为了完整性,请注意还有这样一种东西,即没有封闭实例的内部类:
class A {
int t() { return 1; }
static A a = new A() { int t() { return 2; } };
}
这里,new A(){…}是在静态上下文中定义的内部类,没有封闭实例。
推荐文章
- 在流中使用Java 8 foreach循环移动到下一项
- 访问限制:'Application'类型不是API(必需库rt.jar的限制)
- 用Java计算两个日期之间的天数
- 如何配置slf4j-simple
- 在Jar文件中运行类
- 带参数的可运行?
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 我可以在Java中设置enum起始值吗?
- Java中的回调函数
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 在Java中,流相对于循环的优势是什么?
- Jersey在未找到InjectionManagerFactory时停止工作
- 在Java流是peek真的只是调试?
- Recyclerview不调用onCreateViewHolder
- 将JSON字符串转换为HashMap