【问题标题】:Inner and Nested Classes内部类和嵌套类
【发布时间】:2026-01-10 14:10:01
【问题描述】:

Oracle 文档(在下面的链接中)说:

非静态嵌套类(内部类)可以访问其他成员 封闭类,即使它们被声明为私有。

但在下面的示例中,我创建了一个对象objin(内部类),它无法访问其封闭外部类的任何方法或变量。下面是代码,有大佬能解释一下吗?

http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html

package Package_1;
public class Outer {

    int k;
    public void Multiply()
    {
        System.out.println("inside outer class' method multiply");
    }

    public class Inner {
        int l;
        public void Division()
        {
            System.out.println("inside inner class' method Divison");
        }

    }
}

带有 Main 方法的类

package Package_1;

public class D {

    public static void main(String[] args) {
        Outer objout = new Outer();
        objout.k = 5;
        objout.Multiply();

        Outer.Inner objin = objout.new Inner();
        objin.l = 7;
        objin.Division();          
    }
}

对于 objin 对象,我无法在其封闭类中访问 Multiple 方法。

【问题讨论】:

  • @VigneshVino:是的,他有一个。

标签: java


【解决方案1】:

我看到了你的“隐私”!

从非静态嵌套类(内部类)的代码中,您可以访问封闭类的公共和私有成员。

但它是你的“私人”,不是我的!

这就是您在尝试执行objin.Multiply() 时的想法:您正在访问Multiply(),就好像它是内部类的成员,但事实并非如此。请记住,您可以从内部类的代码中看到它,但它不会像您的一样被暴露出来。

【讨论】:

  • 我喜欢你非常“视觉”的风格。你用什么工具来做这些?
【解决方案2】:

规范是这么说的

public class Outer{
   private int x;
   private void method(){
   }
   public void publicMethod(){} 

   public class Inner{

      //has access to even private properties of x
      method(); //can be called

      //NOTE: Only has ACCESS and does not INHERIT those methods
   }

}

您正在尝试使用Inner 的实例访问publicMethod(),它没有任何该名称的方法。

关键:

非静态嵌套类只能访问容器类的所有属性和方法,但不继承 那些方法。

objin.Multiply() 无法工作,因为症结解释了 Multiply() 是在 Outer 而不是 Inner 上定义的,因此在 Inner 上没有方法 Multiply()

【讨论】:

    【解决方案3】:

    文档并没有说您可以通过使用对内部类的引用来访问外部类的字段和方法。所以你不能这样做

    objin.Multiply();
    

    因为 Multiply 不是 Inner 的方法。你可以做的是:

    public class Inner {
        int l;
        public void Division()
        {
            System.out.println("I can access the field k in outer: " + k);
            System.out.println("I can access the method Multiply in outer (even if Multiply was private): ");
            Multiply();
            // which is a shortcut for
            Outer.this.Multiply();
        }
    }
    

    PS:请尊重 Java 命名约定。方法以小写字母开头。

    【讨论】:

      【解决方案4】:

      您正试图通过使用内部类对象的实例来访问该方法。它只能通过 Outer 类方法在外部访问。您可以直接调用内部类的类定义中的方法,但不能使用内部类的实例。如果您仍然想这样做,请尝试:

      package Package_1;
      public class Outer {
      
      int k;
      public void Multiply()
      {
          System.out.println("inside outer class' method multiply");
      }
      
      public class Inner {
          int l;
          public void Division()
          {
              System.out.println("inside inner class' method Divison");
          }
      
          public void Multiply() {
               Outer.this.Multiply();  //Outer class method.
          }
      
      }
      }
      

      【讨论】:

      • 这将导致 *Error。
      • 为什么会出现堆栈溢出?
      • 我明白了。我需要使用 Outer.this.Multiply();
      • 对不起,我有点困惑,根据 Java 中的面向对象概念,我们可以使用其对象引用或类名(在静态方法的情况下)调用方法。但是,在这种情况下,我们如何在另一个方法中单独调用一个方法——“Multiple():”。这不会与 Java 基础相矛盾吗?
      • Outer.this 保存当前的 Outer 对象引用。所以它不是对 Multiply() 的静态调用