探索基礎之反射——第一章
小白的成長來源於努力學習,堅持每天的積累。 ——半杯態
一、獲取Class型別;
1.型別名.class
這種方式:簡潔,但是編譯期才可以使用。
public void test01() {
Class B1 = int.class; //基本資料型別
Class<Void> voidClass = void.class; // 特殊的空型別
Class<String> stringClass = String.class; //jdk 定義的型別
Class<Serializable> serializableClass = Serializable.class; //獲取介面型別
Class<int[]> arryList = int[].class; // 獲取陣列型別
Class<TestClass> testClassClass = TestClass.class; //自定義型別
Class<ElementType> elementTypeClass = ElementType.class; //列舉型別
System.out.println(elementTypeClass);
}
2.物件.getClass()
這個方法在java.lang.Object型別中宣告的,返回物件的執行時型別
@Test
public void test02() {
Class c2 = String.class;
//重點在student
Student student = new Student();
student.getClass();
Class c1 = "".getClass();
Class<Student> studentClass = Student.class;
System.out.println(studentClass);
System.out.println(c1 == c2);
}
3.Class.forName(“型別全名稱”)
這個型別可以在編譯期間未知,這個類名稱可以在程式碼中出現,也可以配置在配置檔案中,或者鍵盤輸入等方式來指定。
@Test
public void test03() throws ClassNotFoundException {
Class<?> name = Class.forName("com.banbeitai.reflect.Student");
System.out.println(name);
}
4.使用類載入器物件.loadClass(“型別全名稱”)
一般都是用在自定義類載入器物件去載入指定路徑下的類
@Test
public void test04() throws ClassNotFoundException {
Class<TestClass> testClassClass = TestClass.class;
ClassLoader classLoader = testClassClass.getClassLoader();
Class<?> loadClass = classLoader.loadClass("com.banbeitai.reflect.Student");
System.out.println(loadClass);
}
二、反射的作用與運用
1、在執行時能夠獲取任意型別的詳細資訊
2、在執行時能夠建立任意引用資料型別的物件
3、在執行時可以為任意物件的任意屬性賦值,或者獲取任意物件的任意屬性的值
4、在執行時可以呼叫任意物件的任意方法
5、在執行時讀取某個註解資訊
6、在執行時讀取某個類的泛型實參
使用步驟:
(1)獲取這個類的Class物件
(2)獲取類的資訊
①包名②類名③類的修飾符Modifier④直接父類⑤父介面⑥屬性⑦構造器⑧方法
package com.banbeitai.reflect;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.lang.reflect.*;
import java.util.Arrays;
import java.util.Properties;
public class TestClassInfo {
private Class clazz;
@Before
public void loadClass() throws IOException, ClassNotFoundException {
Properties pro = new Properties();
pro.load(TestClassInfo.class.getResourceAsStream("bean.properties"));
String className = pro.getProperty("className");
clazz = Class.forName(className);
System.out.println(className);
}
@Test
public void getProperty() {
//獲取類所在的包名
Package aPackage = clazz.getPackage();
System.out.println("獲取包名:" + aPackage);
//獲取類名
System.out.println("獲取包名:" + clazz.getName());
//獲取類的修飾符
int mod = clazz.getModifiers();
System.out.println("修飾符的值:" + mod);
System.out.println("修飾符:" + Modifier.toString(mod));
//獲取類的父類
System.out.println("父類是:" + clazz.getSuperclass());
//返回該類實現和繼承的介面
Class[] interfaces = clazz.getInterfaces();
for (Class inter : interfaces) {
System.out.println(inter.getName());
}
//每一個屬性就是一個Field的物件
/*
* (1)Field[] getFields() 得到所有公共的屬性 包含本類非私有修飾的以及父級(介面,類)的全部的成員變數
* (2)Field[] getDeclaredFields() 得到所有宣告的屬性
*/
Field[] fields = clazz.getFields();
//Field[] fields = clazz.getDeclaredFields();
int count = 0;
for (Field field : fields) {
count++;
int fMod = field.getModifiers();
System.out.println("序號:" + count + ":屬性名:" + field.getName());
System.out.println("序號:" + count + ":屬性的資料型別:" + field.getType().getName());
System.out.println("序號:" + count + ":屬性的修飾符::" + Modifier.toString(fMod));
}
/*
* Constructor[] getConstructors():得到所有的公共的構造器
* Constructor[] getDeclaredConstructors()():得到所有的宣告的構造器
*/
count = 0;
Constructor[] constructors = clazz.getDeclaredConstructors();
for (Constructor constructor : constructors) {
System.out.println("序號:" + count + ":構造器名字:" + constructor.getName());
int cMod = constructor.getModifiers();
System.out.println("序號:" + count + ":構造器修飾符:" + Modifier.toString(cMod));
Class[] parameterTypes = constructor.getParameterTypes();
Parameter[] parameters = constructor.getParameters();
for (Parameter parameter : parameters) {
System.out.println(parameter.toString());
}
System.out.println(count + ":構造器的形參列表:" + Arrays.toString(parameterTypes));
/* (1)Method[] getMethods(); 得到所有公共的方法
* (2)Method[] getDeclaredMethods(); 得到所有宣告的方法
*/
}
/* (1)Method[] getMethods(); 得到所有公共的方法
* (2)Method[] getDeclaredMethods(); 得到所有宣告的方法
*/
count=0;
Method[] declaredMethods = clazz.getDeclaredMethods();
for (Method method : declaredMethods) {
count++;
int mMod = method.getModifiers();
System.out.println(count + ":方法的修飾符:" + Modifier.toString(mMod));
System.out.println(count +":方法的返回值型別:" + method.getReturnType());
System.out.println(count + ":方法的名稱:" + method.getName());
System.out.print(count + ":丟擲的異常型別們:");
Class<?>[] exceptionTypes = method.getExceptionTypes();
System.out.println(Arrays.toString(exceptionTypes));
Class[] parameterTypes = method.getParameterTypes();
System.out.println(count + ":方法的形參列表:" + Arrays.toString(parameterTypes));
}
}
}
2.1 建立物件
方式一:使用Class物件直接new物件
方式二:使用構造器建立物件
package com.banbeitai.reflect.Demo2;
import org.junit.Test;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.time.LocalDate;
public class TestNewInstance {
//使用反射建立物件
@Test
public void createObject() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
Class<?> forName = Class.forName("com.banbeitai.reflect.demo1.Student");
//通過Class類建立物件
Object instance = forName.newInstance();
System.out.println(instance);
System.out.println("--------通過構造器建立物件---------");
Constructor<?> constructor = forName.getConstructor();
Object newInstance = constructor.newInstance();
System.out.println(newInstance);
System.out.println("--------通過有參構造器建立物件---------");
Constructor<?> nameConstructor = forName.getConstructor(String.class, LocalDate.class);
Object paramConstructor = nameConstructor.newInstance("小米", LocalDate.now());
System.out.println(paramConstructor);
System.out.println("---------------獲取私有構造器---------------------");
Constructor<?> privateonstructor = forName.getDeclaredConstructor(String.class);
//開啟獲取私有修飾內容的許可權
privateonstructor.setAccessible(true);
Object privateObj = privateonstructor.newInstance("小軍");
System.out.println(privateObj);
}
}
2.2 為物件的屬性賦值,以及獲取對應屬性的值
方法 | 含義/解釋 |
---|---|
set(Object obj, Object value) | 為成員屬性設定值,引數介紹:第一個引數是物件,第二引數是屬性的值(Field) |
Object get(Object obj) | 獲取某個屬性的值,引數介紹:物件 |
setAccessible(true) | 開啟訪問許可權,true為可以訪問 |
package com.banbeitai.reflect.Demo2;
import org.junit.Test;
import java.lang.reflect.Field;
import java.time.LocalDate;
public class TestField {
@Test
public void getField() {
//(1)獲取某個型別的Class物件
try {
Class clazz = Class.forName("com.banbeitai.reflect.demo1.Student");
Object newInstance = clazz.newInstance();
Field field = clazz.getDeclaredField("name");
Field localDate = clazz.getDeclaredField("localDate");
localDate.setAccessible(true);
field.setAccessible(true);
field.set(newInstance, "小軍");
localDate.set(newInstance, LocalDate.now());
System.out.println(newInstance);
Object obj = field.get(newInstance);
System.out.println(obj);
System.out.println(localDate.get(newInstance));
} catch (Exception e) {
e.printStackTrace();
}
}
}
2.3 得到所有公共的方法/私有方法 Method類
package com.banbeitai.reflect.Demo3;
import java.lang.reflect.Method;
public class TestFastMethod {
public static void main(String[] args) throws Exception {
//(1)獲取Class物件:四種方式之一
Class clazz = Class.forName("com.banbeitai.reflect.demo1.Student");
//(2)得到方法Method物件
//例如:得到void setInfo(String info)方法
/*
* (1)Method clazz.getMethod(name, parameterTypes):得到公共的方法
* (2)Method clazz.getDeclaredMethod(name, parameterTypes):得到宣告的方法
* 一個類中方法是可能過載,如何定位到某一個方法 方法名 + 形參列表
*/
Method method = clazz.getDeclaredMethod("getInfo", String.class);
//(3)呼叫方法
/*
* 靜態方法:
* 類名.方法(【實參列表】)
* 非靜態方法
* 物件名.方法(【實參列表】)
*/
//建立物件
Object obj = clazz.newInstance();
//呼叫方法
method.invoke(obj, "半杯態");
System.out.println(obj);
//獲取public static void
Method testMethod = clazz.getDeclaredMethod("test", int.class);
//呼叫方法
testMethod.invoke(null, 10);
}
}
相關文章
- Java基礎之反射機制(續)Java反射
- JAVA基礎學習篇之反射Java反射
- 【Java基礎】RTTI與反射之JavaJava反射
- 反射基礎反射
- Java反射—初探反射基礎Java反射
- Java基礎之第一章概述Java
- Java 反射基礎Java反射
- java基礎——反射Java反射
- [Java基礎]反射Java反射
- java框架基礎技術之--------反射機制Java框架反射
- 【Java 反射學習】Java 反射基礎Java反射
- [Java 反射學習] Java 反射基礎Java反射
- Java基礎(十八)反射Java反射
- Java-基礎-反射Java反射
- Java基礎(十一)——反射Java反射
- Java基礎系列—Java反射Java反射
- java基礎 -反射筆記Java反射筆記
- Go基礎學習記錄之反射(reflect)機制Go反射
- 【Java反射】Java 泛型基礎Java反射泛型
- Java基礎——深入理解反射Java反射
- 【Go進階—基礎特性】反射Go反射
- Java基礎--JDBC-反射等JavaJDBC反射
- 【Java基礎】反射和註解Java反射
- Python基礎第一章Python
- 第一章 基礎知識
- 探索ABP基礎架構架構
- java EE開發之Servlet第十一課:反射基礎三JavaServlet反射
- Java重點基礎:反射機制Java反射
- EasyAndroid基礎整合元件庫之:EasyReflect 優雅的反射功能庫Android元件反射
- 探索ABP基礎架構-下架構
- PHP DIY 系列------基礎篇:3. 反射PHP反射
- Java基礎對反射知識總結Java反射
- 基礎篇:深入解析JAVA反射機制Java反射
- 《機器學習實戰》第一章 機器學習基礎機器學習
- 微服務架構基礎(第一章)微服務架構
- 第一章 資訊化基礎知識
- 前端基礎之jQuery基礎前端jQuery
- Java安全基礎之Java反射機制和ClassLoader類載入機制Java反射