本文共 5902 字,大约阅读时间需要 19 分钟。
泛型,即“参数化类型”。就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。
一些常用的泛型类型变量:
泛型类定义的语法为:
[访问修饰符] class 类名称
示例如下:
public class GenericClass{ private T data; // 泛型不能使用在静态属性上 //private static T javaee; public T getData() { return data; } public void setData(T data) { this.data = data; } public static void main(String[] args) { GenericClass genericClass=new GenericClass<>(); genericClass.setData("Generic Class"); System.out.println(genericClass.getData()); }}
泛型接口的使用示例如下:
public interface GenericIntercace{ //接口中泛型字母不能使用在全局常量中 //public static final T MAX_VALUE = 100; //T MAX_VALUE; T getData();}
实现泛型接口方式一:
public class ImplGenericInterface1implements GenericIntercace { private T data; private void setData(T data) { this.data = data; } @Override public T getData() { return data; } public static void main(String[] args) { ImplGenericInterface1 implGenericInterface1 = new ImplGenericInterface1<>(); implGenericInterface1.setData("Generic Interface1"); System.out.println(implGenericInterface1.getData()); }}
实现泛型接口方式二:
public class ImplGenericInterface2 implements GenericIntercace{ @Override public String getData() { return "Generic Interface2"; } public static void main(String[] args) { ImplGenericInterface2 implGenericInterface2 = new ImplGenericInterface2(); System.out.println(implGenericInterface2.getData()); }}
泛型方法定义的语法为:
[访问修饰符] [static]返回值类型 方法名(T 参数列表)
使用示例如下:
public class Method { // 泛型方法,在返回类型前面使用泛型字母 public staticvoid test1(T t){ System.out.println(t); } // T 只能是list 或者list 的子类 public static void test2(T t){ t.add("aa"); } // T... 可变参数 ---> T[] public static void test3(T...a) { for (T temp : a) { try { if (null != temp) { temp.close(); } } catch (Exception e) { e.printStackTrace(); } } } public static void main(String[] args) throws FileNotFoundException { test1("java 是门好语言"); test3(new FileInputStream("a.txt")); }}
使用泛型方法时,至少返回值或参数有一个是泛型定义的,而且应该保持一致,否则可能会受到各种限制。
泛型适用于多种数据类型执行相同的代码(代码复用)。
泛型中的类型在使用时指定,不需要强制类型转换(类型安全,编译器会检查类型)。
限定泛型类型变量:
对类的限定:
public class TypeLimitForClass{ private T data; public T getData() { return data; } public void setData(T data) { this.data = data; } }
对方法的限定:
/** * 限定类型使用extends关键字指定 * 可以使用类、接口,类放在前面接口放在后面用&符号分割 * 例如:& Serializable> */public static > T getMin(T a, T b) { return (a.compareTo(b) < 0) ? a : b;}
泛型中的约束和局限性:
泛型类只能用在成员变量上,只能使用引用类型,基本类型无法作为泛型类型。
// 基本类型无法作为泛型类型// GenericRestrict1 genericRestrictInt = new GenericRestrict1<>();
泛型接口只能用在抽象方法上。
不能实例化泛型类。
/** * 不能实例化泛型类 * Type parameter 'T' cannot be instantiated directly */public void setData() { //this.data = new T();}
静态变量或方法不能引用泛型类型变量,但是静态泛型方法是可以的。
/** * 静态变量或方法不能引用泛型类型变量 * 'com.jay.java.泛型.restrict.GenericRestrict1.this' cannot be referenced from a static context */// private static T result;// private static T getResult() { // return result;// }/** * 静态泛型方法是可以的 */private staticK getKey(K k) { return k;}
无法使用instanceof
关键字或==
判断泛型类的类型。
GenericRestrict1genericRestrictInteger = new GenericRestrict1<>();GenericRestrict1 genericRestrictString = new GenericRestrict1<>();/** * 无法使用instanceof关键字判断泛型类的类型 * Illegal generic type for instanceof */// if(genericRestrictInteger instanceof GenericRestrict1 ){ // return;// }/** * 无法使用“==”判断两个泛型类的实例 * Operator '==' cannot be applied to this two instance */// if (genericRestrictInteger == genericRestrictString) { // return;// }
泛型类的原生类型与所传递的泛型无关,无论传递什么类型,原生类是一样的。
// 泛型类的原生类型与所传递的泛型无关,无论传递什么类型,原生类是一样的System.out.println(normalClassA == normalClassB);//falseSystem.out.println(genericRestrictInteger == genericRestrictInteger);//System.out.println(genericRestrictInteger.getClass() == genericRestrictString.getClass()); //trueSystem.out.println(genericRestrictInteger.getClass());//com.jay.java.泛型.restrict.GenericRestrict1System.out.println(genericRestrictString.getClass());//com.jay.java.泛型.restrict.GenericRestrict1
泛型数组可以声明但无法实例化。
// 泛型数组可以声明但无法实例化GenericRestrict1[] genericRestrict1s;// genericRestrict1s = new GenericRestrict1 [10];genericRestrict1s = new GenericRestrict1[10];genericRestrict1s[0]=genericRestrictString;
泛型类不能继承Exception
或者Throwable
。
/** * 泛型类不能继承Exception或者Throwable * Generic class may not extend 'java.lang.Throwable' */// private class MyGenericExceptionextends Exception { // }//// private class MyGenericThrowable extends Throwable { // }
不能捕获泛型类型限定的异常,但可以将泛型限定的异常抛出。
/** * 不能捕获泛型类型限定的异常 * Cannot catch type parameters */publicvoid getException(T t) { // try { // // } catch (T e) { // // }}/** *可以将泛型限定的异常抛出 */public void getException(T t) throws T { try { } catch (Exception e) { throw t; }}
泛型类型继承规则:
public class ArrayList<E> extends AbstractList<E>
。转载地址:http://friwi.baihongyu.com/