Java 泛型
1:
package com.daxin.fanxing;
import java.util.Arrays;
public class ArrayDemo<T> {
public T[] arr;
public T[] createArray() {
// 信息存在于编译器,即在编译期间知道齐是一个T类型的数组,但是运行期间就是object数组
return (T[]) new Object[10];
}
public static void main(String[] args) {
ArrayDemo<Integer> arr = new ArrayDemo<>();
//运行时没有编译期间信息,因此相当于父类向子类转型报错、
//Integer[] ia = arr.createArray();
//
Object [] objs= arr.createArray();
System.out.println(objs.getClass());
}
}
2:
package com.daxin.fanxing.csdn;
import java.lang.reflect.*;
import java.util.Map;
/**
*
* @author liuguangxin
*
*/
class Score {
// 泛型类型参数类型
//之所以可以获取成员变量的泛型信息是因为成员变量的泛型信息存储在类的metadata中
private Map<String, Integer> score;
}
public class Main {
public static void main(String[] args) {
System.out.println("================获取成员变量信息=================");
Class<Score> cls = Score.class;
try {
// 2 获取Score的成员变量
Field field_score = cls.getDeclaredField("score");
// 3 获取普通类型参数
Class<?> type_score = field_score.getType();
System.out.println(type_score.getName());
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
System.out.println("==============获取成员变量的泛型信息===================");
cls = Score.class;
try {
// 2 获取Score的成员变量
Field field = cls.getDeclaredField("score");
// 3 获取成员变量的泛型类型
Type type = field.getGenericType();
// 4 强制转换为ParameterizedType
if (type instanceof ParameterizedType) {
ParameterizedType pType = (ParameterizedType) type;
// 5 获取泛型类型参数
Type[] tArgs = pType.getActualTypeArguments();
for (Type t : tArgs) {
System.out.println(t.toString());
}
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
}
3:
package com.daxin.fanxing;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
class Test {
public List<String> list = new ArrayList<String>();
}
/**
* 通过反射方法调用破坏容器的泛型约束
*/
public class Test2 {
/**
* 泛型方法,具体类型由接受的变量的类型确定
* @return
*/
public static<T> List<T> getList(){
return new ArrayList<T>();
}
public static <T> void printT(T t){
System.out.println(t);
}
public static void main(String[] args) throws Exception {
getList();//返回的是一个List<Object>的list,因为没有接受值所以无法进行类型推断
System.out.println(getList().getClass());
List<String> strs = getList();
System.out.println(strs.getClass());
printT(strs);
//泛型方法如果必须要传入泛型参数的话,则需在"."与方法名字之间使用“<Type>”即可
Test2.<Test>printT(new Test());
Field[] fields = Test.class.getDeclaredFields();
Test obj = new Test();
for (Field f : fields) {
List fv = (List) f.get(obj);
fv.add(55);
Type type = f.getGenericType();
System.out.println(fv + " " + type);
//385-
}
}
public static void test2(String[] args) {
List list1 = new ArrayList();
List<String> list2 = new ArrayList<String>();
list2.add("Hello");
// list2.add(20); //报错
Class c1 = list1.getClass();
Class c2 = list2.getClass();
System.out.println(c1 == c2); // true 证明类型已经被擦除
/**
* 反射操作都是编译之后的操作 c1==c2结果返回true,说明编译之后集合的泛型是去泛型化的
* java中集合的泛型是为了防止错误输入的,只在编译阶段有效,绕过编译就无效了 验证:通过方法的反射来绕过编译
*/
Method[] ms = c2.getDeclaredMethods();
System.out.println("=====================================================================");
for (Method m : ms) {
String mName = m.getName();
if (!mName.equals("add"))
continue;
Type[] type = m.getGenericParameterTypes();
System.out.println(mName + " " + Arrays.toString(type));
}
System.out.println("=====================================================================");
try {
Method m = c2.getMethod("add", Object.class);
//破坏泛型约束
m.invoke(list2, 20);
System.out.println(list2);
} catch (Exception e) {
e.printStackTrace();
}
}
}

浙公网安备 33010602011771号