java中无法访问匿名内部类成员

java中无法访问匿名内部类成员,java,inner-classes,anonymous-class,anonymous-inner-class,Java,Inner Classes,Anonymous Class,Anonymous Inner Class,当我使用匿名内部类创建节点时。当我打印所有键时,它们打印为0,而不是我在匿名类声明中指定的值。我做错什么了吗?这是我的密码: public class LinkedListTest { Node head; public void addInOrder(final int value) { if (head == null) { head = new Node() { int key = value; }; } e

当我使用匿名内部类创建节点时。当我打印所有键时,它们打印为0,而不是我在匿名类声明中指定的值。我做错什么了吗?这是我的密码:

public class LinkedListTest {
Node head;

public void addInOrder(final int value) {
    if (head == null) {
        head = new Node() {
            int key = value;
        };
    }
    else if(head.key > value) {
        final Node temp = head;
        head = new Node() {
            int key = value;
            Node next = temp;
        };
    }
    else {
        Node theNode = head;
        while(theNode.key < value) {
            if (theNode.next == null) {
                theNode.next = new Node() {
                    int key = value;
                };
                return;
            }
            else if(theNode.next.key > value) {
                final Node temp = theNode.next;
                theNode.next = new Node() {
                    int key = value;
                    Node next = temp;
                };
                return;
            }
            theNode = theNode.next;
        }
    }
}
这是我的打印方法:

  public void printAll(Node hasNode) {
    if (hasNode != null) {
        System.out.println(hasNode.key);
        if (hasNode.next != null) {
            printAll(hasNode.next);
        }
    }
}

这是因为您没有给
节点中的字段赋值,而是给匿名子类中同名的字段赋值

将构造函数添加到
节点
,不要创建匿名子类:

class Node {
  int key;
  Node next;

  Node(int key, Node next) {
    this.key = key; this.next = next;
  }
}
或者,您可以添加第二个构造函数,该构造函数只接受密钥:

  Node(int key) {
    this(key, null);
  }

另一种方法是只调用
新节点(key,null)

这是因为您没有给
节点中的字段赋值,而是给匿名子类中同名的字段赋值

将构造函数添加到
节点
,不要创建匿名子类:

class Node {
  int key;
  Node next;

  Node(int key, Node next) {
    this.key = key; this.next = next;
  }
}
或者,您可以添加第二个构造函数,该构造函数只接受密钥:

  Node(int key) {
    this(key, null);
  }

另一种方法是调用
newnode(key,null)

正如Andy Turner回答的那样,您在匿名类中声明了
key
next
作为匿名类的实例变量,并且您正在初始化这些实例变量,但是它们与类
节点中同名的实例变量无关

如果这能让人更容易理解,那么:

theNode.next = new Node() {
    int key = value;
    Node next = temp;
};
相当于如下所示的本地类:

class Foo extends Node {
    int key = value;
    Node next = temp;
};
theNode.next = new Foo();
或者,您甚至可以将类从方法中提升出来,以便捕获更加清晰:

// outside the method
class Foo extends Node {
    int key;
    Node next;
    Foo(int value, Node temp) { key = value; next = temp; }
};
// inside the method
theNode.next = new Foo(value, temp);
关键是,在所有这些情况下,您都是为
Foo
的实例变量赋值,而不是为
节点的实例变量赋值

您可以在匿名类中执行初始化,该类允许您分配给
节点的实例变量。尽管匿名类没有构造函数(它们不需要构造函数),但可以在实例初始值设定项中进行初始化:

theNode.next = new Node() {
    {
        key = value;
        next = temp;
    }
};
它通常以“双大括号初始化”样式编写:


正如Andy Turner所回答的,您在匿名类中将
key
next
声明为匿名类的实例变量,并且您正在初始化这些实例变量,但它们与类
节点中同名的实例变量无关

如果这能让人更容易理解,那么:

theNode.next = new Node() {
    int key = value;
    Node next = temp;
};
相当于如下所示的本地类:

class Foo extends Node {
    int key = value;
    Node next = temp;
};
theNode.next = new Foo();
或者,您甚至可以将类从方法中提升出来,以便捕获更加清晰:

// outside the method
class Foo extends Node {
    int key;
    Node next;
    Foo(int value, Node temp) { key = value; next = temp; }
};
// inside the method
theNode.next = new Foo(value, temp);
关键是,在所有这些情况下,您都是为
Foo
的实例变量赋值,而不是为
节点的实例变量赋值

您可以在匿名类中执行初始化,该类允许您分配给
节点的实例变量。尽管匿名类没有构造函数(它们不需要构造函数),但可以在实例初始值设定项中进行初始化:

theNode.next = new Node() {
    {
        key = value;
        next = temp;
    }
};
它通常以“双大括号初始化”样式编写:


安迪领先我几秒钟:-),但是的,这就是发生的事情。
int键=值在匿名子类中声明并初始化一个实例变量,该变量覆盖了
节点中同名的字段。我明白,但是如果我分配给匿名内部类的值字段不能在其声明的范围之外访问,那么匿名内部类的意义何在?我认为“阴影”在这种情况下会起作用。谢谢你的反馈!匿名内部类有许多用途,它们不涉及声明同名的成员变量。但是,在匿名内部类中声明的任何成员变量或非重写方法(几乎)都是不可访问的,因为您只是引用了
节点,而不是
链接列表测试$1
节点的特定子类(“几乎”是因为您可以像
新节点(){int foo=5;}那样访问它们.foo
;但这是一件非常不寻常的事情,也不是很有用)谢谢,我不知道在使用匿名内部类时,成员基本上是无法访问的。Andy领先了我几秒钟:-),但是的,这就是发生的事情。
int键=值在匿名子类中声明并初始化一个实例变量,该变量覆盖了
节点中同名的字段。我明白,但是如果我分配给匿名内部类的值字段不能在其声明的范围之外访问,那么匿名内部类的意义何在?我认为“阴影”在这种情况下会起作用。谢谢你的反馈!匿名内部类有许多用途,它们不涉及声明同名的成员变量。但是,在匿名内部类中声明的任何成员变量或非重写方法(几乎)都是不可访问的,因为您只是引用了
节点,而不是
链接列表测试$1
节点的特定子类(“几乎”是因为您可以像
新节点(){int foo=5;}那样访问它们.foo
;但这是一件非常不寻常的事情,也不是很有用)谢谢,我不知道在使用匿名内部类时,成员基本上是不可访问的。