Java 实例化内部类

Java 实例化内部类,java,inner-classes,Java,Inner Classes,我正在处理一个过度删除hashCode和equals方法的示例问题,但得到一个错误:“无法访问CustomHashCodeExample类型的封闭实例。必须使用CustomHashCodeExample类型的封闭实例限定分配(例如x.new a(),其中x是CustomHashCodeExample的实例)。” 我编写了一个内部类HashPerson,当我试图在另一个名为testHashCodeOverride()的方法中实例化这个内部类时,遇到了这个错误 尽管我没有看到静态的内部类或外部类的实

我正在处理一个过度删除hashCode和equals方法的示例问题,但得到一个错误:“无法访问CustomHashCodeExample类型的封闭实例。必须使用CustomHashCodeExample类型的封闭实例限定分配(例如x.new a(),其中x是CustomHashCodeExample的实例)。” 我编写了一个内部类HashPerson,当我试图在另一个名为testHashCodeOverride()的方法中实例化这个内部类时,遇到了这个错误

尽管我没有看到静态的内部类或外部类的实例化,但这段代码运行良好:(


您需要使内部类成为静态的,或者通过外部类的实例引用它。很可能您只想使内部类成为静态的


类的非静态成员(变量、方法、内部类)是该类的每个实例。因此,当从静态上下文访问非静态成员时(例如
testHashCodeOverride
等静态方法),您需要指定封闭类的实例。

我认为您希望将
HashPerson
类声明为
static
。否则,它只能在包含类的上下文中实例化,或者在包含类的方法中实例化,或者使用如下代码:

ContainingClass container = new ContainingClass();
HashPerson william = container.new HashPerson("willy");

实际上,我的经验法则是使任何嵌套类都是静态的,除非我有特殊的理由不这样做。这也是更有效的,因为非静态嵌套类(称为内部类)总是包含对包含对象的隐式引用。

正如我所见,实例化内部类可能有不同的方法

  • 静态内部类:当内部类是静态的时,假设代码如所述

    class OuterClass 
    {
        static int outer_x = 10;
        int outer_y = 20;
        // static nested class 
        static class StaticNestedClass {
            void display() {
    
            }
        }
    }
    
    OuterClass.StaticNestedClass nestedObject =
     new OuterClass.StaticNestedClass();
    
  • 或者这对于静态类来说就足够了

     new StaticNestedClass();
    
  • 本地内部类(非静态):非静态的内部类,本地内部类的一个优点是它们可以访问封闭类的所有私有数据成员

    OuterClass outerObject = new OuterClass(); 
    OuterClass.InnerClass innerObject = outerObject.new InnerClass();
    
  • 匿名内部类(实现接口):这种类型的类通常是隐藏的,人们无法在代码中直接看到类{…}块,这就是为什么称为匿名内部类。这里描述了如何在内部类实现接口可运行接口的情况下实例化它

    Runnable r = new Runnable() 
    { 
      //This is Anonymous Class
      public void run() {
        System.out.println("Child Thread");
      }
    };
    
  • 匿名内部类(扩展一个类):我们可以有一个匿名内部类来扩展一个类,这里我以线程类为例

    Thread t = new Thread(new Runnable() 
    {
      //Anonymous Inner class
    public void run() {
        System.out.println("Child Thread");
    }
    });
    
  • 定义内部方法/构造函数参数的匿名内部类:内部类也可以在方法中定义,这里给出了如何在参数中定义和实例化它的示例

    public static void main(String[] args) 
    { 
    //Here we are using Anonymous Inner class 
    //that define inside argument, here constructor argument 
    Thread t = new Thread(new Runnable() 
    { 
        public void run() 
        { 
            System.out.println("Child Thread"); 
        } 
    });
    t.start();
    

  • 您是否确实阅读了错误消息?它确切地告诉您要做什么。当实例化内部类时,必须使用封闭类的实例对其进行限定。您应该真正清理示例代码的格式,并将其精简为基本内容。在当前状态下,这几乎是不可读的。您可以简化
    hashCode
    方法返回name.hashCode();@Jonik:谢谢你清理了代码格式。我还没有足够的声誉来这么做。不过这让我有点困惑。当我查看代码时,它应该会产生相同的“无封闭实例”错误,因为静态方法
    testHashCodeOverride
    想要实例化非静态嵌套(=内部)类
    HashPerson
    @Steve的对象,这是一个演示如何在所有场景中重写hashcode的示例,我只是在自己身上尝试了同样的方法。name.hashcode();将返回内存地址,对吗?嗨,oksayt,所以在大多数情况下,我们应该使内部类为静态的?首选方法是什么?通过外部类或静态的实例访问?不要将内部类用于公共API。内部类被添加为具有闭包和匿名类。默认情况下,顶级类是静态的,但内部类是静态的ses是非静态的。如果您只是为了代码组织的目的而创建一个内部类,那么将其设置为
    静态的
    ,并将其视为一个独立的类(具有限制可见性的选项)是首选。如果您需要内部类访问其封闭类的非静态成员,则应将其设置为非静态。感谢MForster,我所困惑的地方,我有一个示例程序,它的编写方式与我在这里的编写方式完全相同,在该代码中,内部类不是静态的,而且它们也没有创建INSTACT“我的问题中的附加代码”他们是否在包含类的方法中创建实例?可能我没有正确阅读代码。只是发布了实际代码。>>因为非静态嵌套类(称为内部类)始终包含对包含对象的隐式引用。MForster,为什么内部类引用包含类不好?它需要内存。顺便说一下,您发布的代码不可读。但在我看来,在这种情况下,HashPerson类似乎是顶级类,而不是嵌套类。
    
    Thread t = new Thread(new Runnable() 
    {
      //Anonymous Inner class
    public void run() {
        System.out.println("Child Thread");
    }
    });
    
    public static void main(String[] args) 
    { 
    //Here we are using Anonymous Inner class 
    //that define inside argument, here constructor argument 
    Thread t = new Thread(new Runnable() 
    { 
        public void run() 
        { 
            System.out.println("Child Thread"); 
        } 
    });
    t.start();