一、反射的概念
是指在運行過程中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調用這個對象的所有方法和屬性。這種動態獲取信息和動態調用方法的功能稱為JAVA的反射機制。
二、反射的優缺點
2.1、優點
通過反射的概念我們已經知道反射的優點是:使程序能夠訪問到裝載到JVM中的類的內部信息(成員變量和成員方法)
2.2、缺點
性能問題:反射是一種解釋操作,通過反射來訪問字段和調用方法時要慢于直接代碼
使用反射會模糊程序內部邏輯:反射繞過了源代碼,使用反射后開發人員無法通過查看源代碼來判斷業務邏輯,會帶來維護問題。使用反射往往比直接代碼更復雜。
ps:Java反射機制主要應用在對靈活性和擴展性要求很高的系統框架上,普通程序不建議使用。
三、反射的使用
3.1、使用反射API來實例化對象
第一步獲取Class實例,有三種方式
Class.forName(是不是很熟悉,JDBC通常通過此方式來獲取數據庫連接驅動類)
.class
getClass()
第二步使用Class的方法來實例化對象,有兩種方式
第一種方式newInstance()
第二種方式
Constructor constructor = clazz.getConstructor();
constructor.newInstance();
話不多說,趕緊上代碼
package com.cc.reflect.bean;public class Student
{private int id;private String name;@Overridepublic String toString(){return "Student [id=" + id + ", name=" + name + "]";}
}
package com.cc.reflect;import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;import com.cc.reflect.bean.Student;/*** * @描述: 使用反射API來實例化對象* @版權: Copyright (c) 2019 * @作者: 程沖* @版本: 1.0 * @創建日期: 2019年5月17日 * @創建時間: 上午8:35:04*/
public class InstanceStudent
{public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, SecurityException, IllegalArgumentException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException{//1 第一步獲取Class實例
// Class clazz = getClassByFullName("com.cc.reflect.bean.Student");//適用于知道類的完整路徑名Class clazz = getClassByName();//適用于編譯前就明確要操作的類
// Student student = new Student();Class clazz = getClassByObject(student);//適用于存在可以操作的實例//2 第二步使用Class的方法來實例化對象
// Object obj = getInstance1(clazz);//直接通過字節碼文件來實例化對象,必須有無參構造器Object obj = getInstance2(clazz);//通過構造對象來實例化對象//3 第三步對象初始化Field fieldId = clazz.getDeclaredField("id");fieldId.setAccessible(true);fieldId.set(obj, 1);Field fieldName = clazz.getDeclaredField("name");fieldName.setAccessible(true);fieldName.set(obj, "張三");//上面的方法破壞了類成員的訪問規則,一般不建議這么做System.out.println(obj);}private static Class getClassByFullName(String fullName) throws ClassNotFoundException{return Class.forName(fullName);}private static Class getClassByName(){return Student.class;}private static Class getClassByObject(Object obj){return obj.getClass();}private static Object getInstance1(Class clazz) throws InstantiationException, IllegalAccessException{return clazz.newInstance();}private static Object getInstance2(Class clazz) throws SecurityException, NoSuchMethodException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException{Constructor constructor = clazz.getConstructor();return constructor.newInstance();}
}
ps:本文只介紹了使用反射來實例化對象,有興趣可以自己去研究一下如何訪問類的屬性、調用類的方法,比較簡單。