0

当我使用匿名内部类创建节点时。当我打印所有的键,他们打印为0,而不是我在匿名类声明中分配的值。难道我做错了什么?这里是我的代码:匿名内部类成员在java中不可访问

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; 
     } 
    } 
} 

这是我为我的节点类声明:

class Node { 
    int key; 
    Node next; 
} 

这是我的打印方法:

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

回答

3

这是因为你不分配值分配给Node中的字段,则您将为具有相同名称的匿名子类中的字段赋值。

添加一个构造函数来Node,并且不创建一个匿名子类:

class Node { 
    int key; 
    Node next; 

    Node(int key, Node next) { 
    this.key = key; this.next = next; 
    } 
} 

或者,您可以添加第二个构造函数只需要关键:

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

另一种方法是只需拨打new Node(key, null)

+0

安迪打败了我几秒钟:-),但是,这就是发生了什么。匿名子类中的'int key = value;'声明并初始化匿名子类中的实例变量,该实例变量覆盖'Node'中相同名称的字段。 – blm

+0

我明白了,但是如果我赋值给它们的值字段,匿名内部类的最后一点是不能在它们声明的范围之外访问的?我认为在这种情况下“阴影”会起作用。 感谢您的反馈! –

+0

匿名内部类有很多用途,不涉及声明相同名称的成员变量。但是,在匿名内部类中声明的任何成员变量或非重写方法几乎都是不可访问的,因为您只需引用“Node”,而不是“NodeList”的特定子类LinkedListTest $ 1。 –

0

安迪·特纳回答说,你在你的匿名类为匿名类的实例变量声明keynext,并且要初始化这些实例变量,但他们无关,从类Node同名的实例变量。

如果它会更容易理解,这一点:

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); 

的观点是,在所有这些情况下,您要分配值s到实例变量Foo,而不是实例变量Node

您可以在匿名类中执行初始化,使您可以分配给实例变量Node。虽然匿名类没有构造函数(他们并不需要他们),初始化可以在实例初始化完成:

theNode.next = new Node() { 
    { 
     key = value; 
     next = temp; 
    } 
}; 

它经常写在“双大括号初始化”样式:

theNode.next = new Node() {{ 
    key = value; 
    next = temp; 
}};