java基礎語法(三十九)—反射機制(二)
反射的概述
java在計算機中獎勵的三個階段如下圖所示:
框架:半成品軟體。可以在框架的基礎上進行軟體開發,簡化編碼。
反射:將類的各個組成部分封裝為其他物件,這就是反射機制。
好處:
- 可以在程式執行過程中操作這些物件
- 可以解耦,提高程式的可擴充套件性
獲取Class物件的方式: - Class.forName(“全類名”):將位元組碼檔案載入記憶體,返回Class物件
- 類名.class:通過類名的屬性class獲取
- 物件.getClass():getClass()方法在Object類中定義
結論:
同一個位元組碼檔案(*.class)在一次程式執行過程當中,只會被載入一次,無論是通過哪一種方式獲取的Class物件都是同一個
Constructor:構造方法
建立物件:
T newInstance(Object… initargs)
如果使用空引數的構造方法建立物件,操作可以簡化:Class物件的newInstance方法
Method:方法物件
執行方法:
Object invoke(Object obj,Object… args) 傳遞真實的物件以及方法的實際引數列表
獲取方法名稱:
String getName:獲取方法名
獲取Class物件的三種方式
- 獲取Class物件的方式:
-
- Class.forName(“全類名”):將位元組碼檔案載入記憶體,返回Class物件
多用於配置檔案,將類名定義在配置檔案中。讀取檔案,載入類
- Class.forName(“全類名”):將位元組碼檔案載入記憶體,返回Class物件
-
- 類名.class:通過類名的屬性class獲取
多用於引數的傳遞
- 類名.class:通過類名的屬性class獲取
-
- 物件.getClass():getClass()方法在Object類中定義
多用於物件的獲取位元組碼的方式
- 物件.getClass():getClass()方法在Object類中定義
public class ReflectDemo1 {
public static void main(String[] args) throws Exception {
//1. Class.forName(“全類名”)
Class cls1=Class.forName("com.company.reflect.domain.Person");
System.out.println(cls1);//class com.company.reflect.domain.Person
//2. 類名.class
Class cls2= Person.class;
System.out.println(cls2);
//3. 物件.getClass()
Person p=new Person();
Class cls3=p.getClass();
System.out.println(cls3);
//==比較三個物件
System.out.println(cls1==cls2);//true
System.out.println(cls1==cls3);//true
}
}
Class物件功能概述
- Class物件功能
- 獲取功能:
- 獲取成員變數們
-
Field[] getFields() 獲取所有public修飾的成員變數
-
Field getField(String name)獲取指定名稱的public修飾的成員變數
-
Field[] getDeclaredFields()
-
Field getDeclaredField(String name)
- 獲取構造方法們
-
Constructor<?>[] getConstructors()
-
Constructor<T> getConstructor(類<?>... parameterTypes)
-
Constructor<T>getDeclaredConstructor(類<?>... parameterTypes)
-
Constructor<?>[] getDeclaredConstructors()
- 獲取成員方法們
-
Method[] getMethods()
-
Method getMethod(String name,類<?>... parameterTypes)
-
Method[] getDeclaredMethods()
-
Method getDeclaredMethod(String name,類<?>... parameterTypes)
- 獲取類名
-
String getName()
public class ReflectDemo2 {
public static void main(String[] args) throws Exception {
//0 獲取Person的Class物件
Class personClass=Person.class;
/*
獲取成員變數們
Field[] getFields()
Field getField(String name)
Field[] getDeclaredFields()
Field getDeclaredField(String name)
*/
//1.Field[] getFields() 獲取所有public修飾的成員變數
Field[] fields=personClass.getFields();
for (Field field : fields) {
System.out.println(field);//public java.lang.String com.company.reflect.domain.Person.a
}
System.out.println("----------------------------");
//2.Field getField(String name)
Field a=personClass.getField("a");
//獲取成員變數a的值
Person p=new Person();
Object value=a.get(p);
System.out.println(value);//null
//設定a的值
a.set(p,"張三");
System.out.println(p);
System.out.println("------------------------");
//3. Field[] getDeclaredFields():獲取所有的成員變數,不考慮修飾符
Field[] declaredFields=personClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println(declaredField);
}
//4. Field getDeclaredField(String name)
Field d=personClass.getDeclaredField("d");
//忽略訪問許可權修飾符的安全檢查
d.setAccessible(true);//暴力反射
Object value2=d.get(p);
System.out.println(value2);
}
}
public class ReflectDemo3 {
public static void main(String[] args) throws Exception {
//0 獲取Person的Class物件
Class personClass=Person.class;
/*
獲取構造方法們
Constructor<?>[] getConstructors()
Constructor<T> getConstructor(類<?>... parameterTypes)
Constructor<T>getDeclaredConstructor(類<?>... parameterTypes)
Constructor<?>[] getDeclaredConstructors()
*/
// Constructor<T> getConstructor(類<?>... parameterTypes)
Constructor constructor=personClass.getConstructor(String.class,int.class);
System.out.println(constructor);//public com.company.reflect.domain.Person(java.lang.String,int)
//建立物件
Object person=constructor.newInstance("張三",23);
System.out.println(person);
System.out.println("--------------------------------------------------");
Constructor constructor1=personClass.getConstructor( );
System.out.println(constructor1);//public com.company.reflect.domain.Person(java.lang.String,int)
//建立物件
Object person1=constructor1.newInstance( );
System.out.println(person1);
Object o=personClass.newInstance();
System.out.println(o);
}
}
public class ReflectDemo4 {
public static void main(String[] args) throws Exception {
//0 獲取Person的Class物件
Class personClass=Person.class;
/*
獲取成員方法們
Method[] getMethods()
Method getMethod(String name,類<?>... parameterTypes)
Method[] getDeclaredMethods()
Method getDeclaredMethod(String name,類<?>... parameterTypes)
*/
//獲取指定名稱的方法
Method eat_method=personClass.getMethod("eat");
Person p=new Person();
//執行方法
eat_method.invoke(p);
Method eat_method2 =personClass.getMethod("eat",String.class);
//執行方法
eat_method2.invoke(p,"飯");
System.out.println("--------------------------------");
//獲取所有public修飾的方法
Method[] methods=personClass.getMethods();
for (Method method : methods) {
System.out.println(method);
//method.setAccessible(true);
String name=method.getName();
System.out.println(name);
}
//獲取類名
String className=personClass.getName();
System.out.println(className);
}
}
反射的案例
要求:
可以建立任意類的物件,可以執行任意方法
前提:不能改變該類的任何程式碼,可以建立任意類的物件,可以執行任意方法
先建立兩個類
Person類:
package com.company.reflect.domain;
public class Person {
private String name;
private int age;
public String a;
protected String b;
String c;
private String d;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", a='" + a + '\'' +
", b='" + b + '\'' +
", c='" + c + '\'' +
", d='" + d + '\'' +
'}';
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void eat(){
System.out.println("eat...");
}
public void eat(String food){
System.out.println("eat..."+food);
}
}
Student類
package com.company.reflect.domain;
public class Student {
public void sleep(){
System.out.println("sleep...");
}
}
import com.company.reflect.domain.Person;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;
/**
* 框架類
*/
public class ReflectTest {
public static void main(String[] args) throws Exception {
//1.載入配置檔案
//1.1建立Properties物件
Properties pro=new Properties();
//1.2 載入配置檔案,轉換為一個集合
//1.2.1 獲取class目錄下的配置檔案
ClassLoader classLoader=ReflectTest.class.getClassLoader();//獲取ReflectTest類物件所在的類載入器,通過該類載入器獲得配置檔案所在的路徑
InputStream is=classLoader.getResourceAsStream("pro.properties");//該方法獲得資源所對應的位元組流
pro.load(is);
//2.獲取配置檔案中定義的資料
String className=pro.getProperty("className");
String methodName=pro.getProperty("methodName");
//3.載入該類進記憶體
Class cls=Class.forName(className);
//4.建立物件
Object obj=cls.newInstance();
//5.獲取方法物件
Method method=cls.getMethod(methodName);
//6.執行方法
method.invoke(obj);
}
}
配置檔案在根目錄下生成(pro.properties 配置如下)
className=com.company.reflect.domain.Person
methodName=eat
相關文章
- Java基礎之反射機制(續)Java反射
- Java重點基礎:反射機制Java反射
- 基礎篇:深入解析JAVA反射機制Java反射
- Java基礎語法:運算子、包機制、JavaDocJava
- java框架基礎技術之--------反射機制Java框架反射
- Java安全基礎之Java反射機制和ClassLoader類載入機制Java反射
- java基礎:深入理解Class物件與反射機制Java物件反射
- Java基礎-語法基礎Java
- Java反射機制Java反射
- Java 基礎語法Java
- JAVA語法基礎Java
- Java反射—初探反射基礎Java反射
- Python基礎語法(二)Python
- 【Java 反射學習】Java 反射基礎Java反射
- [Java 反射學習] Java 反射基礎Java反射
- Java基礎 —— 反射Java反射
- [Java基礎]反射Java反射
- Java 反射基礎Java反射
- Java的反射機制Java反射
- Java核心反射機制Java反射
- java利器——反射機制Java反射
- Java基礎語法1Java
- JAVA基礎語法(一)Java
- Java基礎系列—Java反射Java反射
- Java-基礎-反射Java反射
- Java基礎(十一)——反射Java反射
- Java基礎(十八)反射Java反射
- Java基礎語法筆記Java筆記
- Java基礎 語法筆記Java筆記
- JavaSE之java基礎語法Java
- Java基礎語法吐血整理Java
- Java反射機制簡答Java反射
- Java 中的 反射機制Java反射
- Java反射機制那些事Java反射
- 第二課 Python基礎語法Python
- java--實驗二語法基礎練習(2)AXJava
- Java基礎-基礎語法-變數與常量Java變數
- 【Java反射】Java 泛型基礎Java反射泛型