1. Java非静态内部类与外部类的引用
在Java中,非静态内部类(也被称为内嵌类或嵌套类)确实默认持有其外部类的一个引用。这是因为非静态内部类可以访问外部类的实例成员(包括字段和方法),这要求它能够识别到具体的外部类实例。这种引用在字节码层面是可见的,但直接查看字节码文件(如.class文件)可能不太直观。不过,可以通过反编译工具(如JD-GUI、javap等)来观察内部类的结构,从而间接验证这一点。
示例代码:
java
public class OuterClass {
private int outerField = 10;
public class InnerClass {
public void show() {
System.out.println(outerField); // 访问外部类的实例变量
}
}
public static void main(String[] args) {
OuterClass outer = new OuterClass();
OuterClass.InnerClass inner = outer.new InnerClass();
inner.show();
}
}
在这个例子中,InnerClass是OuterClass的非静态内部类,InnerClass的实例inner隐式地持有了OuterClass的实例outer的引用,从而能够访问outerField。
2. 静态方法与非静态方法的synchronized锁
synchronized关键字在Java中用于控制对共享资源的并发访问,以防止数据不一致。当synchronized修饰静态方法时,它锁定的是调用该方法的类的Class对象;而当它修饰非静态方法时,它锁定的是调用该方法的对象实例。
与第1点的联系:
锁对象的不同
:静态方法的锁(Class对象的锁)与非静态内部类持有的外部类实例的锁是不同的。静态方法的锁是类级别的,而非静态内部类实例持有的锁是外部类实例级别的。
影响范围
:由于锁定的对象不同,因此它们的影响范围也不同。静态方法的锁会影响所有该类的实例,因为它们是共享同一个Class对象的。而非静态方法的锁只影响特定的实例,因为每个实例都有自己独立的锁。
内存可见性和同步:虽然锁对象不同,但两者都遵循Java内存模型中的同步规则,确保了被同步代码块的内存可见性和有序性。
应用场景
:静态方法的synchronized常用于控制对类级别资源的并发访问,如静态字段的修改;而非静态方法的synchronized则用于控制对实例级别资源的并发访问,如实例字段的修改。
总的来说,虽然非静态内部类与外部类的引用和synchronized锁定的对象在Java中扮演着不同的角色,但它们都涉及到了Java的并发控制机制,特别是关于对象锁和内存模型的理解。