Java内部类与外围类泛型参数
来源:互联网 发布:安顺浪人网络官网 编辑:程序博客网 时间:2024/05/30 04:48
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<T> prev; private Node<T> next; public Node(T data,Node<T> prev,Node<T> next) { this.data=data; this.prev=prev; this.next=next; } } private int size; private int modCount=0; private Node<T> begin; private Node<T> 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<T> iterator() { // TODO Auto-generated method stub return new LinkedListIterator(); } // 非静态内部迭代类 private class LinkedListIterator implements Iterator<T> { private Node<T> current=begin.next; private int expectedModCount=modCount; private boolean okToRemove=false; /*一些方法实现 *hasNext() *next() *remove() */ }}
泛型类实现泛型接口
- 泛型类声明的泛型参数占主导地位,如泛型类声明的参数为
<T>
,则泛型接口的泛型参数也应为<T>
; - 当泛型类声明的参数为
<T>
时,泛型接口的参数<T>
可以不写; - 当泛型接口的参数为
<T>
时,潜在表明泛型类的参数为<T>
,必须在泛型类中声明<T>
。
// 规范写法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 typepublic class MyClass1 implements Iterator<T> { /* implementaion */}
非静态内部类会自动继承外围类泛型参数
在LinkedList
实现中:存在一个静态内部类private static class Node<T>
,一个非静态内部类LinkedListIterator
,并且该非静态内部类实现了Iterator<T>
。
按照规范写法,LinkedListIterator
的形式应当是在LinkedListIterator
中声明泛型参数<T>
,如下所示。
private class LinkedListIterator<T> implements Iterator<T> { private Node<T> current=begin.next; private int expectedModCount=modCount; private boolean okToRemove=false; /* implementaion */}
但这样private Node<T> current=begin.next;
就会报错,类型不匹配,
Type mismatch: cannot convert from MyLinkedList.Node to MyLinkedList.Node
经过Google一番得知,对于非静态内部类,会自动继承外围类的泛型参数,即LinkedListIterator
已经有默认的泛型参数<T>
,而这里又重新声明一个新的泛型参数<T>
,两者并不相同。
结论:对于非静态内部类,无需再次声明泛型参数
静态内部类不会自动继承外围类泛型参数
事实上,Node<T>
中的泛型参数<T>
与MyLinkedList<T>
中的<T>
没有任何联系,只是这里使用相同的符号T
而已。
一些测试
对内部类和外围类的泛型参数之间的关系进行一些测试
import java.util.Iterator;public class GenericType<T> { public static void main(String[] args) { // TODO Auto-generated method stub GenericType<Integer> a=new GenericType<>(new Integer(5)); MyClass<Integer> b=new MyClass<>(a.getX()); MyClass2<Integer> 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; } // 非静态内部类会自动继承外部类的泛型 // 这里又重新声明了一个新的泛型<T> // Inner1<T>中声明的<T>与Demo11<T>中的<T>不同 // 导致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 } // 需去掉<T> private class Inner2 { T y=x; } // 需去掉<T>,接口应写为<T> private class Inner6 implements MyInterface<T> { T y=x; } // 接口写为其他,如<E>均报错// private class Inner7 implements MyInterface<E> {// E y; // E cannot be resolved to a type// } // 静态内部类不会自动继承外部类的泛型,相当于独立于外部类 // 可以自己声明泛型 private static class Inner3<T> { T z=new GenericType<T>().x; } // 可以自己声明泛型,并且不需要和外部类的泛型声明相同 private static class Inner4<V> { V v=new GenericType<V>().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; }}
刚学编程不久,欢迎大家探讨交流!
0 0
- Java内部类与外围类泛型参数
- java内部类----安全问题-----访问外围类的私有变量
- 泛型类的非静态内部类可访问外围类的类型参数
- JAVA 内部类与静态内部类
- Java内部类与静态内部类
- Java内部类与静态内部类
- Java内部类与匿名内部类
- JAVA内部类 与 匿名内部类
- Java 内部类与匿名内部类
- java内部类与静态内部类
- Java 内部类与匿名内部类
- Java内部类与匿名内部类
- Java -> 内部类与匿名内部类
- 内部类实现一个接口与外围类实现这个接口的区别
- java接口与内部类
- java 内部类与static
- Java接口与内部类
- java接口与内部类
- C\C++控制台程序隐藏方法总结
- 数组-2分查找2
- 雾浓度白天/晚上解帧逻辑
- 查看一组日期的最大最小的方法
- thymeleaf 学习笔记-基础篇
- Java内部类与外围类泛型参数
- 千兆电口互通
- Android四大组件之一的Service使用
- lanproxy可支持任何 tcp 上层协议(ssh 访问、web 服务器访问、远程桌面...)
- bzoj1017: [JSOI2008]魔兽地图
- view getLeft(), getRight(), getTop(), getBottom()都是0
- jxls2.3-简明教程
- 排序
- Mac系统下的Eclipse代码联想功能开启代码联想功能