1. 程式人生 > >javaSE (四十一)反射的概念、通過反射越過泛型檢查

javaSE (四十一)反射的概念、通過反射越過泛型檢查

作為javaSE的最後一篇,反射更多的是一種程式設計理念或者說優化,對前面的java多型的一種優化,簡單但是需要理解一下

這篇文章寫的很好:
大白話說Java反射:入門、使用、原理


1、反射的概念:

  • 反射是相對於正射來說的,正射是先通過構造方法建立類的物件,然後使用類的各種屬性和方法
  • 而反射是什麼時候想要用到這個類了,就通過類名把這個類載入進來,然後獲得構造方法,獲得屬性和方法,更加地可持續

方法:

獲得類.class

大部分應用的是第一種,指導類名(完整的,包名+類名)可以和config配置檔案結合起來
在這裡插入圖片描述

下面寫一個程式碼包括以下的反射用法:

  1. 通過類名獲得類
  2. 通過無參構造獲得物件,需要從class向下轉型
  3. 指定有參建構函式 ,引數都是位元組碼
  4. 用這個有參構造物件
  5. 獲得欄位(私有private屬性)
  6. 去除私有許可權
  7. 修改欄位
  8. 獲得無參方法
  9. 獲得有參方法

例項程式碼:

package reflection;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Reflection {
public static void main(String[] args) throws Exception { Class clazz = Class.forName("reflection.Student");//1、通過類名獲得類 Student s = (Student) clazz.newInstance();//2、通過無參構造獲得物件,需要從class向下轉型 Constructor con = clazz.getConstructor(String.class,int.class); //3、指定有參建構函式,引數都是位元組碼 //T newInstance(Object... initargs)
Student str1 = (Student) con.newInstance("吳彥祖",23); //4、用這個有參構造物件 //Field field = clazz.getField("name");//5、獲得欄位(共有public屬性) Field field = clazz.getDeclaredField("name");//5、獲得欄位(私有private屬性) field.setAccessible(true); //6、去除私有許可權 field.set(str1, "PziAn"); //7、修改欄位 System.out.println(str1); //輸出:Student [name=PziAn, age=23] //方法 getMethod(String name, 類<?>... parameterTypes) Method method1 = clazz.getMethod("eat"); //8、獲得無參方法 method1.invoke(str1); //輸出:吃魷魚絲! Method method2 = clazz.getMethod("eat",int.class); //9、獲得有參方法 method2.invoke(str1,8); //輸出:吃魷魚絲8次! } } 輸出: Student [name=PziAn, age=23] 吃魷魚絲 吃魷魚絲8次!

2、通過反射越過泛型檢查:

泛型只是在編譯階段起作用,執行階段會被擦除,所以我們在編譯後拿到這個類的位元組碼,可以做一些事情,比如在ArrayList<Integer> 中放String型別的數

編譯:將檔案.java變成機器能識別的位元組碼.class

例項程式碼:

package reflection;

import java.lang.reflect.Method;
import java.util.ArrayList;

public class ArrayListwithreflection {

	public static void main(String[] args) throws Exception {
		ArrayList<Integer> list = new ArrayList<>();
		list.add(111);
		list.add(222);

		Class clazz = Class.forName("java.util.ArrayList");
		// 獲得add方法

		Method method = clazz.getMethod("add", Object.class);// 注意這裡是object

		method.invoke(list, "南京是一座很美的城市!");

		System.out.println(list);

	}

}
輸出:

[111, 222, 南京是一座很美的城市!]