Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 对象具有所有类成员的副本(静态成员除外),因此对象也具有内部类的副本吗?_Java_Oop_Static_Inner Classes - Fatal编程技术网

Java 对象具有所有类成员的副本(静态成员除外),因此对象也具有内部类的副本吗?

Java 对象具有所有类成员的副本(静态成员除外),因此对象也具有内部类的副本吗?,java,oop,static,inner-classes,Java,Oop,Static,Inner Classes,对象具有所有类成员的副本(静态成员除外),因此对象也具有内部类的副本吗 下面是我的代码: package com.example; class outerClass{ class innnerClass{ } } public class A{ public void main(String[] args){ outerCla

对象具有所有类成员的副本(静态成员除外),因此对象也具有内部类的副本吗

下面是我的代码:

    package com.example;

        
    class outerClass{
        
         class innnerClass{
            
            }
    }


    public class A{

      public void main(String[] args){
        outerClass obj1 = new outerClass();

        outerClass.innerClass obj2 = obj1.new innerClass();
      }
    }

我怀疑obj2是“作为outerClass成员的innerClass”的实例还是“作为obj1对象成员的innerClass”的实例。外部类的每个实例都将拥有自己的非静态内部类副本。

我们之所以知道这一点,是因为给定类的每个实例都将收到该类所有非静态成员的副本,如下所述:

当从同一个类蓝图创建多个对象时,每个对象都有各自不同的实例变量副本

由于非静态内部类实际上是该类的实例成员,因此每次创建外部类的新实例时,都会创建该类的唯一副本。换句话说,复制非静态内部类就像复制非静态方法或字段一样


此外,您不能在非静态内部类()中声明任何静态成员,考虑到非静态内部类不存在其外部类的实例,这是有意义的。由于非静态内部类的唯一副本是为其外部类的每个实例创建的,因此它不能包含任何静态成员。

当您查看类似的内容时,您可能会发现这样一句话

当从同一个类蓝图创建多个对象时,每个对象都有各自不同的实例变量副本

注意,它说的是变量,而不是成员。但即便如此,这也过于简单化了。这实际上意味着,对象的实例变量可以有不同的值。变量的定义(包括注释及其值)是不变的,将它们复制到对象将导致无意义的相同副本

同样,方法的声明(包括它们的代码)是不变的,因此,复制它们是没有意义的。但是在实例上操作的方法的有效行为可能不同,因为它们可能在不同的值上操作

这同样适用于内部类。它们的定义是不变的,不需要复制它们。但非静态内部类实例与外部实例关联,外部实例可能具有不同的字段值,这可能导致内部类方法的不同行为

在您的示例中,外部类中没有实例字段,内部类中也没有方法,这取决于外部对象的状态,因此使用哪个外部实例来实例化内部类对象没有区别(除了对垃圾收集的一些小影响)

将状态添加到外部实例并将依赖行为添加到内部实例时,情况会发生变化:

公共类外部{
布尔偶数;
外部(布尔偶数){
这个。偶数=偶数;
}
班级内部{
@凌驾
公共字符串toString(){
返回偶数?“偶数”:“奇数”;
}
}
公共静态void main(字符串[]args){
内部i1=新的外部(真)。新的内部();
内部i2=新的外部(错误)。新的内部();
系统输出打印LN(i1);
系统输出println(i2);
}
}
这里,两个
内部
实例由于用于创建它们的外部对象而表现出不同的行为。不过,这并不意味着类定义被复制

从JDK16开始,您将能够向内部类添加静态成员。在这一点上,重要的是内部类不被每个外部实例复制,换句话说,内部类的静态成员在运行时只存在一次,就像顶级或嵌套静态类的静态成员一样

我们可以将示例更改为

公共类外部{
布尔偶数;
外部(布尔偶数){
这个。偶数=偶数;
}
班级内部{
静止的{
System.out.println(“内部初始化”);
}
@凌驾
公共字符串toString(){
返回偶数?“偶数”:“奇数”;
}
}
公共静态void main(字符串[]args){
内部i1=新的外部(真)。新的内部();
内部i2=新的外部(错误)。新的内部();
系统输出打印LN(i1);
系统输出println(i2);
}
}

这将适用于JDK 16及更新版本,并只打印一次“内部初始化”,而不是两次。

您的代码中有输入错误。声明中有三个n,当你试图使用innnerClass时有两个“object拥有所有类成员的副本”-你从哪里得到这种智慧?我建议你再仔细阅读引用的文本。请注意,它没有说“成员”。此外,请注意链接的问题。@Holger您是对的。我不知道为什么我认为上面写着“成员”。。。很明显,我没有很好地校对我的答案。无论如何,你的答案比我的准确得多。