-
泛型,即“参数化类型”。就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。
-
一些常用的泛型类型变量:
- E:元素(Element),多用于java集合框架
- K:关键字(Key)
- N:数字(Number)
- T:类型(Type)
- V:值(Value)
- K,V:代表Map的键值对(Key,Value)
-
泛型类定义的语法为:
[访问修饰符] class 类名称 <T>
示例如下:
public class GenericClass<T> { 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<String> genericClass=new GenericClass<>(); genericClass.setData("Generic Class"); System.out.println(genericClass.getData()); } }
-
泛型接口的使用示例如下:
public interface GenericIntercace<T> { //接口中泛型字母不能使用在全局常量中 //public static final T MAX_VALUE = 100; //T MAX_VALUE; T getData(); }
实现泛型接口方式一:
public class ImplGenericInterface1<T> implements GenericIntercace<T> { private T data; private void setData(T data) { this.data = data; } @Override public T getData() { return data; } public static void main(String[] args) { ImplGenericInterface1<String> implGenericInterface1 = new ImplGenericInterface1<>(); implGenericInterface1.setData("Generic Interface1"); System.out.println(implGenericInterface1.getData()); } }
实现泛型接口方式二:
public class ImplGenericInterface2 implements GenericIntercace<String> { @Override public String getData() { return "Generic Interface2"; } public static void main(String[] args) { ImplGenericInterface2 implGenericInterface2 = new ImplGenericInterface2(); System.out.println(implGenericInterface2.getData()); } }
-
泛型方法定义的语法为:
[访问修饰符] [static] <T> 返回值类型 方法名(T 参数列表)
使用示例如下:
public class Method { // 泛型方法,在返回类型前面使用泛型字母 public static <T> void test1(T t){ System.out.println(t); } // T 只能是list 或者list 的子类 public static <T extends List> void test2(T t){ t.add("aa"); } // T... 可变参数 ---> T[] public static <T extends Closeable> 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<T extends List & Serializable> { private T data; public T getData() { return data; } public void setData(T data) { this.data = data; } }
-
对方法的限定:
/** * 限定类型使用extends关键字指定 * 可以使用类、接口,类放在前面接口放在后面用&符号分割 * 例如:<T extends ArrayList & Comparable<T> & Serializable> */ public static <T extends Comparable<T>> T getMin(T a, T b) { return (a.compareTo(b) < 0) ? a : b; }
-
-
泛型中的约束和局限性:
-
泛型类只能用在成员变量上,只能使用引用类型,基本类型无法作为泛型类型。
// 基本类型无法作为泛型类型 // GenericRestrict1<int> 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 static <K> K getKey(K k) { return k; }
-
无法使用
instanceof
关键字或==
判断泛型类的类型。GenericRestrict1<Integer> genericRestrictInteger = new GenericRestrict1<>(); GenericRestrict1<String> genericRestrictString = new GenericRestrict1<>(); /** * 无法使用instanceof关键字判断泛型类的类型 * Illegal generic type for instanceof */ // if(genericRestrictInteger instanceof GenericRestrict1<Integer>){ // return; // } /** * 无法使用“==”判断两个泛型类的实例 * Operator '==' cannot be applied to this two instance */ // if (genericRestrictInteger == genericRestrictString) { // return; // }
-
泛型类的原生类型与所传递的泛型无关,无论传递什么类型,原生类是一样的。
// 泛型类的原生类型与所传递的泛型无关,无论传递什么类型,原生类是一样的 System.out.println(normalClassA == normalClassB);//false System.out.println(genericRestrictInteger == genericRestrictInteger);// System.out.println(genericRestrictInteger.getClass() == genericRestrictString.getClass()); //true System.out.println(genericRestrictInteger.getClass());//com.jay.java.泛型.restrict.GenericRestrict1 System.out.println(genericRestrictString.getClass());//com.jay.java.泛型.restrict.GenericRestrict1
-
泛型数组可以声明但无法实例化。
// 泛型数组可以声明但无法实例化 GenericRestrict1<String>[] genericRestrict1s; // genericRestrict1s = new GenericRestrict1<String>[10]; genericRestrict1s = new GenericRestrict1[10]; genericRestrict1s[0]=genericRestrictString;
-
泛型类不能继承
Exception
或者Throwable
。/** * 泛型类不能继承Exception或者Throwable * Generic class may not extend 'java.lang.Throwable' */ // private class MyGenericException<T> extends Exception { // } // // private class MyGenericThrowable<T> extends Throwable { // }
-
不能捕获泛型类型限定的异常,但可以将泛型限定的异常抛出。
/** * 不能捕获泛型类型限定的异常 * Cannot catch type parameters */ public <T extends Exception> void getException(T t) { // try { // // } catch (T e) { // // } } /** *可以将泛型限定的异常抛出 */ public <T extends Throwable> void getException(T t) throws T { try { } catch (Exception e) { throw t; } }
-
-
泛型类型继承规则:
- 对于泛型参数是继承关系的泛型类之间时没有继承关系的。
- 泛型类可以继承其它泛型类,例如:
public class ArrayList<E> extends AbstractList<E>
。 - 泛型类的继承关系在使用中同样会受到泛型类型的影响。
Java基础学习笔记4——泛型
最新推荐文章于 2023-03-03 01:21:15 发布