【问题标题】:Why don't need to parameterize with generic inner class?为什么不需要使用泛型内部类进行参数化?
【发布时间】:2020-04-15 18:43:48
【问题描述】:

尝试使用自定义链表编写自定义(但众所周知的)堆栈通用实现。但算法不是重点。我的问题是,为什么不需要参数化

class Node<T>

以及声明

Node <T> top;  //pointer to next node

会不会是多余的?为什么?或者可能需要使用另一个字符,例如&lt;U&gt;?

public class Stack<T> {
        //T is the type parameter
        Node top; //topmost element of stack

        //defines each node of stack
        class Node{
           T value; //value of each node
           Node next;  //pointer to next node

           public Node(T value){
             this.value=value;  //initializing
             next=null;
           }
        }
        //This function pushes new element
        public void push(T value){
         Node current=new Node(value);
         if(isEmpty())
            top=current; //if empty stack
         else{
            current.next=top;
            top=current;
         }
        }
        //This function pops topmost element
        public T pop(){
         T value=null;
         if(!isEmpty()){
             top=top.next;
             value=top.value;
         }
         return value;  //returning popped value
        }

【问题讨论】:

  • 因为它是一个非静态类,它可以访问封闭类的T。如果您拥有Node&lt;T&gt;,那么NodeT 将是不同 TStack&lt;T&gt; 关联的Stack&lt;T&gt;(即内部类'T 将隐藏外部类'T)。

标签: java generics inner-classes


【解决方案1】:

请注意,这里的 Node 类不是 static。这意味着Stack 的每个实例 都有自己的Node 类。像任何其他成员一样,它可以访问其封闭类'T

【讨论】:

  • 为什么不需要Node top?
  • 见最后一句话。
  • 可以访问什么?真正的答案是:那么 Node 的 T 将与与 Stack 关联的 T 不同
【解决方案2】:

如果您的 Node 类是它自己的顶级类(在它自己的 .java 文件中),那么它需要一个通用参数,正如您所期望的那样。我建议你这样做。

但是,因为它是 Stack 的(非静态)内部类,它可以访问 Stackinstance 中的所有内容,包括所有通用信息。

【讨论】:

    【解决方案3】:

    会不会是多余的?

    是的。

    为什么?

    由于Node被声明为Stack的内部类,变量TNode的范围内,可以根据需要使用。

    或者可能需要使用其他字符,例如&lt;U&gt;?

    如果您需要声明一个不同的类型变量,您可以这样做。 (实际上,您可能应该使用不同的变量名。)它可能看起来像这样:

    public class Stack<T> {
    
        Node<T> top;                               // CHANGE HERE
    
         class Node<U> {                           // CHANGE HERE
            U value;                               // CHANGE HERE
            Node<U> next;                          // CHANGE HERE
    
            public Node(U value) {                 // CHANGE HERE
                this.value = value;
                next = null;
            }
        }
    
        public void push(T value) {
            Node<T> current = new Node<>(value);   // CHANGE HERE
            if (isEmpty())
                top = current;
            else {
                current.next = top;
                top = current;
            }
        }
    
        public T pop() {
            T value = null;
            if (!isEmpty()) {
                top = top.next;
                value = top.value;
            }
            return value;
        }
    

    这说明添加额外的类型变量会导致更多代码,并且不会提高可读性。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-01
      • 2022-01-25
      • 1970-01-01
      相关资源
      最近更新 更多