Java内部类与外围类泛型参数

Java内部类与外围类泛型参数

在Java的编程中,经常使用常规内部类和静态内部类(即嵌套类),当外围类和内部类都是用泛型参数时,会存在一些需要注意的问题。

问题的起源

LinkedList的Java实现:

import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.NoSuchElementException;

public class MyLinkedList<T> implements Iterable<T> {

    // 静态内部类,定义节点结构
    private static class Node<T> {
        private T data;
        private Node prev;
        private Node next;

        public Node(T data,Node prev,Node next) {
            this.data=data;
            this.prev=prev;
            this.next=next;
        }
    }

    private int size;
    private int modCount=0;
    private Node begin;
    private Node end;

    /*一些方法实现
    *clear()
    *size()
    *isEmpty()
    *add(T x)
    *add(int index, T x)
    *get(int index)
    *remove(int index)
    */

    public MyLinkedList() {
        // TODO Auto-generated constructor stub
    //  clear();
    }


    @Override
    public Iterator iterator() {
        // TODO Auto-generated method stub
        return new LinkedListIterator();
    }

    // 非静态内部迭代类
    private class LinkedListIterator implements Iterator<T> {

        private Node current=begin.next;
        private int expectedModCount=modCount;
        private boolean okToRemove=false;

        /*一些方法实现
        *hasNext()
        *next()
        *remove()
        */


    }


}

泛型类实现泛型接口

  • 泛型类声明的泛型参数占主导地位,如泛型类声明的参数为,则泛型接口的泛型参数也应为
  • 当泛型类声明的参数为时,泛型接口的参数可以不写;
  • 当泛型接口的参数为时,潜在表明泛型类的参数为,必须在泛型类中声明
// 规范写法
public class MyClass1<T> implements Iterator<T> {

    @Override
    public boolean hasNext() {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public T next() {
        // TODO Auto-generated method stub
        return null;
    }

}
// 不规范写法
public class MyClass1<T> implements Iterator {

    /* implementaion */

}
// 错误写法: T cannot be resolved to a type
public class MyClass1 implements Iterator<T> {

    /* implementaion */

}

非静态内部类会自动继承外围类泛型参数

LinkedList实现中:存在一个静态内部类private static class Node,一个非静态内部类LinkedListIterator,并且该非静态内部类实现了Iterator

按照规范写法,LinkedListIterator的形式应当是在LinkedListIterator中声明泛型参数,如下所示。

private class LinkedListIterator<T> implements Iterator<T> {

    private Node current=begin.next;
    private int expectedModCount=modCount;
    private boolean okToRemove=false;

    /* implementaion */
}

但这样private Node current=begin.next;就会报错,类型不匹配,
Type mismatch: cannot convert from MyLinkedList.Node to MyLinkedList.Node

经过Google一番得知,对于非静态内部类,会自动继承外围类的泛型参数,即LinkedListIterator已经有默认的泛型参数,而这里又重新声明一个新的泛型参数,两者并不相同。

结论:对于非静态内部类,无需再次声明泛型参数

静态内部类不会自动继承外围类泛型参数

事实上,Node中的泛型参数MyLinkedList中的没有任何联系,只是这里使用相同的符号T而已。

一些测试

对内部类和外围类的泛型参数之间的关系进行一些测试

import java.util.Iterator;

public class GenericType<T> {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        GenericType a=new GenericType<>(new Integer(5));
        MyClass b=new MyClass<>(a.getX());

        MyClass2 c=new MyClass2<>();
    }

    private T x;

    public GenericType(T x) {
        // TODO Auto-generated constructor stub
        this.x=x;
    }

    public GenericType() {
        // TODO Auto-generated constructor stub

    }


    public T getX() {
        return x;
    }

    public void setX(T x) {
        this.x = x;
    }



    // 非静态内部类会自动继承外部类的泛型
    // 这里又重新声明了一个新的泛型
    // Inner1中声明的与Demo11中的不同
    // 导致T y=x;报错:Type mismatch: cannot convert from T to T
    private class Inner1<T> {
//      T y=x;
    }

    private class Inner5<K> {
//      K y=x; // Type mismatch: cannot convert from T to K
    }

    // 需去掉
    private class Inner2 {
        T y=x;
    }

    // 需去掉,接口应写为
    private class Inner6 implements MyInterface<T> {
        T y=x;
    }

    // 接口写为其他,如均报错
//  private class Inner7 implements MyInterface {
//      E y; // E cannot be resolved to a type
//  }

    // 静态内部类不会自动继承外部类的泛型,相当于独立于外部类
    // 可以自己声明泛型
    private static class Inner3<T> {
        T z=new GenericType().x;
    }

    // 可以自己声明泛型,并且不需要和外部类的泛型声明相同
    private static class Inner4<V> {
        V v=new GenericType().x; 
    }

}


interface MyInterface<E> {

}

class MyClass<R> {
    private R r;
    public MyClass(R r) {
        // TODO Auto-generated constructor stub
        this.r=r;
    }
}


class MyClass1<T> implements Iterator<T> {

    @Override
    public boolean hasNext() {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public T next() {
        // TODO Auto-generated method stub
        return null;
    }

    /* implementation */

}


class MyClass2<V> implements Iterator {

    @Override
    public boolean hasNext() {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public Object next() {
        // TODO Auto-generated method stub
        return null;
    }

}

刚学编程不久,欢迎大家探讨交流!

你可能感兴趣的:(java,泛型,内部类)