
image.png

image.png
反射
JAVA反射機(jī)制是在運(yùn)行狀態(tài)中,對于任意一個(gè)類,都能夠知道這個(gè)類的所有屬性和方法;對于任意一個(gè)對象,都能夠調(diào)用它的任意一個(gè)方法和屬性;這種動(dòng)態(tài)獲取的信息以及動(dòng)態(tài)調(diào)用對象的方法的功能稱為java語言的反射機(jī)制。
要想解剖一個(gè)類,必須先要獲取到該類的字節(jié)碼文件對象。而解剖使用的就是Class類中的方法.所以先要獲取到每一個(gè)字節(jié)碼文件對應(yīng)的Class類型的對象.
類初始化時(shí)機(jī)
1. 創(chuàng)建類的實(shí)例
2. 訪問類的靜態(tài)變量,或者為靜態(tài)變量賦值
3. 調(diào)用類的靜態(tài)方法
4. 使用反射方式來強(qiáng)制創(chuàng)建某個(gè)類或接口對應(yīng)的java.lang.Class對象
5. 初始化某個(gè)類的子類
6. 直接使用java.exe命令來運(yùn)行某個(gè)主類
類加載器
1.負(fù)責(zé)將.class文件加載到內(nèi)在中,并為之生成對應(yīng)的Class對象
2. 雖然我們不需要關(guān)心類加載機(jī)制,但是了解這個(gè)機(jī)制我們就能更好的理解程序的運(yùn)行。
3. Bootstrap ClassLoader 根類加載器
4. Extension ClassLoader 擴(kuò)展類加載器
5. Sysetm ClassLoader 系統(tǒng)類加載器
實(shí)例
package com.the151suggestions.reflect;
/**
* Created by wanggs on 2017/7/23.
* 所有類的對象其實(shí)都是Class的實(shí)例。
* 1. 反射就是通過Class文件對象,去使用文件中的成員變量,構(gòu)造方法,成員方法
* 2. 首先得到Class文件對象,其實(shí)就是得到Class類的對象
* Class:
* 成員變量: Field
* 構(gòu)造方法: Construction
* 成員方法: Method
* 獲取class對象的方式
* A:Object類的getClass()
* B:數(shù)據(jù)類型的靜態(tài)屬性
* C: Class類中的靜態(tài)方法
* Public static Class forNmae(String className)// 類的全路徑
*/
public class ReflectDemo {
public static void main(String[] args) throws ClassNotFoundException {
// 獲取Class文件對象
// 方式 1
Person person = new Person();
Class c = person.getClass();
// 方式 2
Class c1 = Person.class;
// 方式 3
Class c2 = Class.forName("com.the151suggestions.reflect.Person");
System.out.println(c1 == c2); // true
System.out.println(c2); // 輸出 class com.the151suggestions.reflect.Person
}
}
class Person {
private String name;
public int age;
public String address;
public Person() {
}
public Person(String name, int age, String address) {
this.name = name;
this.age = age;
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", address='" + address + '\'' +
'}';
}
// 方法
public void show() {
System.out.println("Person.show");
}
public void method(String s) {
System.out.println("s = " + s);
}
public String getString(String s, int i) {
return "s = " + s + "i = " + i;
}
private void function() {
System.out.println("Person.function");
}
}
通過反射獲取構(gòu)造方法并使用
-
獲取構(gòu)造方法
getConstructors
getDeclaredConstructors
實(shí)例
public class ReflectDemo {
public static void main(String[] args) throws ClassNotFoundException {
// 獲取Class文件對象
Class c2 = Class.forName("com.the151suggestions.reflect.Person");
// 獲取構(gòu)造方法
Constructor[] classes = c2.getConstructors(); // 私有拿不到
for (Constructor constructor : classes){
System.out.println(constructor);
}
}
}
/**
* public com.the151suggestions.reflect.Person(java.lang.String,int,java.lang.String)
public com.the151suggestions.reflect.Person(int)
public com.the151suggestions.reflect.Person(java.lang.String)
public com.the151suggestions.reflect.Person()
*/
public class ReflectDemo {
public static void main(String[] args) throws ClassNotFoundException {
// 獲取Class文件對象
Class c2 = Class.forName("com.the151suggestions.reflect.Person");
// 獲取構(gòu)造方法
Constructor[] classes = c2.getDeclaredConstructors(); // 獲取所有
for (Constructor constructor : classes){
System.out.println(constructor);
}
}
}
-
創(chuàng)建對象
newInstance()
con.newInstance(“zhangsan", 20);
實(shí)例
public class ReflectDemo {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
// 獲取Class文件對象
Class c2 = Class.forName("com.the151suggestions.reflect.Person");
// 獲取單個(gè) public Constructor<T> getConstructor(Class<T>... args)
Constructor constructor = c2.getConstructor(String.class); // 構(gòu)造方法對象
// Person p = new Person("tom);
// public T newInstance(object... arg) 獲取構(gòu)造方法
Person person = (Person) constructor.newInstance("tom");
System.out.println(person );
}
}
私有構(gòu)造暴力訪問
public class ReflectDemo {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
// 獲取Class文件對象
Class c2 = Class.forName("com.the151suggestions.reflect.Person");
// 獲取單個(gè) public Constructor<T> getConstructor(Class<T>... args)
Constructor constructor = c2.getDeclaredConstructor(String.class); // 私有構(gòu)造方法對象
// 暴力訪問
constructor.setAccessible(true); // 取消java語言檢查
Person person = (Person) constructor.newInstance("tom");
System.out.println(person );
person.show();
}
}
通過反射獲取成員變量并使用
-
獲取所有成員
getFields,getDeclaredFields
-
獲取單個(gè)成員
getField,getDeclaredField
- 修改成員的值
set(Object obj,Object value) //將指定對象變量上此 Field 對象表示的字段設(shè)置為指定的新值。
實(shí)例
public class ReflectDemo {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
// 獲取Class文件對象
Class c2 = Class.forName("com.the151suggestions.reflect.Person");
// 獲取所有成員變量
Field[] fields = c2.getDeclaredFields();// 包含私有
for (Field field : fields) {
System.out.println(field);
/**
* public int com.the151suggestions.reflect.Person.age
public java.lang.String com.the151suggestions.reflect.Person.address
*/
}
Constructor constructor = c2.getConstructor();
Object object = constructor.newInstance();
// 獲取單個(gè)
Field field = c2.getField("address");
// 設(shè)置值 public void set(Object obj, Object value)
field.set(object,"鄭州");
// Person p = new Person("鄭州");
System.out.println(object);
}
}
通過反射獲取成員方法并使用
-
獲取所有方法
getMethods
getDeclaredMethods
實(shí)例
public class ReflectDemo {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
// 獲取Class文件對象
Class c2 = Class.forName("com.the151suggestions.reflect.Person");
Method[] methods = c2.getMethods(); // 包括父親的公共方法
for(Method method : methods){
System.out.println(method);
}
}
}
-
獲取單個(gè)方法
getMethod
getDeclaredMethod
實(shí)例
public class ReflectDemo {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
// 獲取Class文件對象
Class c2 = Class.forName("com.the151suggestions.reflect.Person");
Constructor constructor = c2.getConstructor();
Object object = c2.newInstance();
/**
* Person p = new Person();
* p.show();
*/
// 獲取單個(gè) public Method getMethod(String name,Class<?> args);
Method method = c2.getMethod("show");
// 調(diào)用方法 public Object invoke(Object object,Object...args );
method.invoke(object); // 調(diào)用object對的show方法
}
}
方法多個(gè)參數(shù)
public class ReflectDemo {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
// 獲取Class文件對象
Class c2 = Class.forName("com.the151suggestions.reflect.Person");
Constructor constructor = c2.getConstructor();
Object object = c2.newInstance();
/**
* Person p = new Person();
* p.show();
*/
// 獲取單個(gè) public Method getMethod(String name,Class<?> args);
Method method = c2.getMethod("show");
// 調(diào)用方法 public Object invoke(Object object,Object...args );
method.invoke(object);
Method method1 = c2.getMethod("method", String.class);
method1.invoke(object,"tom");
Method method2 = c2.getMethod("getString",String.class,int.class);
String s = (String) method2.invoke(object,"jack",12);
System.out.println(s);
}
}
-
暴力訪問
method.setAccessible(true);
案例
public class Test {
public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
// 加載數(shù)據(jù)
Properties properties = new Properties();
FileReader reader = new FileReader("1.txt");
properties.load(reader);
reader.close();
// 獲取數(shù)據(jù)
String className = properties.getProperty("className");
String methodName = properties.getProperty("methodName");
// 反射
Class c = Class.forName(className);
// 無參構(gòu)造
Constructor constructor = c.getConstructor();
// 創(chuàng)建對象
Object object = c.newInstance();
// 調(diào)用方法
Method method = c.getMethod(methodName);
method.invoke(object);
}
}
案例操作集合
/**
* Created by wanggs on 2017/7/23.
*/
public class ArrayListDemo {
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
/**
* ArrayList<Integer> 中添加字符串
*/
ArrayList<Integer> arrayList = new ArrayList<Integer>();
arrayList.add(12);
Class c = arrayList.getClass();
Method method = c.getMethod("add", Object.class);
method.invoke(arrayList, "tom");
System.out.println(arrayList);
}
}
案例
package com.the151suggestions.reflect01;
import java.lang.reflect.Field;
/**
* Created by wanggs on 2017/7/23.
* public void setProperty(Object obj, String propertyName, Object value){}
* 此方法可將obj對象中名為propertyName的屬性的值
*/
public class Tool {
public void setProperty(Object object, String propertyName, Object value) throws NoSuchFieldException, IllegalAccessException {
Class c = object.getClass();
// 獲取成員變量
Field field = c.getDeclaredField(propertyName);
// 防止私有方法暴力訪問
field.setAccessible(true);
field.set(object,value);
}
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
Dog dog = new Dog();
Tool tool = new Tool();
tool.setProperty(dog,"name","花花");
System.out.println(dog);
}
}
class Dog{
String name;
public Dog() {
}
public Dog(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
'}';
}
}
動(dòng)態(tài)代理
package com.the151suggestions.reflect01;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* Created by wanggs on 2017/7/23.
*/
public class MyinvocationHandler implements InvocationHandler {
private Object target; // 目標(biāo)對象
public MyinvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// Object proxy: 被代理對象 Method method: 要調(diào)用的方法 Object[] args: 方法調(diào)用說填入的參數(shù)
System.out.println("權(quán)限認(rèn)證");
Object o = method.invoke(target, args); // 調(diào)用方法傳入真實(shí)主題和參數(shù)
System.out.println("日志記錄");
return o; // 代理對象
}
}
package com.the151suggestions.reflect01;
import java.lang.reflect.Proxy;
/**
* Created by wanggs on 2017/7/23.
*/
public class UserDaoTest {
public static void main(String[] args) {
StudentDao studentDao = new StudentDaoImpl();
MyinvocationHandler myinvocationHandler = new MyinvocationHandler(studentDao);
StudentDao studentDao1 = (StudentDao) Proxy.newProxyInstance(studentDao.getClass().getClassLoader(),studentDao.getClass().getInterfaces(),myinvocationHandler);
studentDao1.login();
}
}
package com.the151suggestions.reflect01;
/**
* Created by wanggs on 2017/7/23.
*/
public interface UserDao {
public abstract void add();
public abstract void edit();
public abstract void delete();
}
package com.the151suggestions.reflect01;
/**
* Created by wanggs on 2017/7/23.
*/
public class UserDaoImpl implements UserDao {
@Override
public void add() {
System.out.println("權(quán)限校驗(yàn)");
System.out.println("UserDaoImpl.add");
System.out.println("日志記錄");
}
@Override
public void edit() {
System.out.println("UserDaoImpl.edit");
}
@Override
public void delete() {
System.out.println("UserDaoImpl.delete");
}
}
1.接口定義一個(gè)人類的統(tǒng)稱
/**
* Created by wanggs on 2017/7/14.
*/
public interface Human {
public abstract void laugh();
public abstract void cry();
public abstract void talk();
}
2.然后定義具體的人種:
package com.wanggs.factory;
/**
* Created by wanggs on 2017/7/14.
*/
public class WhiteHuman implements Human {
@Override
public void laugh() {
System.out.println("WhiteHuman.laugh");
}
@Override
public void cry() {
System.out.println("WhiteHuman.cry");
}
@Override
public void talk() {
System.out.println("WhiteHuman.talk");
}
}
package com.wanggs.factory;
/**
* Created by wanggs on 2017/7/14.
*/
public class YellowHuman implements Human {
@Override
public void laugh() {
System.out.println("YellowHuman.laugh");
}
@Override
public void cry() {
System.out.println("YellowHuman.cry");
}
@Override
public void talk() {
System.out.println("YellowHuman.talk");
}
}
3.人的工廠
package com.wanggs.factory;
/**
* Created by wanggs on 2017/7/14.
*/
public class HumanFactory {
// 第一版
/* public static Human produceHuman(String type) {
if ("yellow".equals(type)) {
return new YellowHuman();
} else if ("white".equals(type)) {
return new WhiteHuman();
} else if ("black".equals(type)) {
return new BlackHuman();
}
System.out.println("有誤");
return null;
}*/
//第二版
/* public static Human produceYellow() {
return new YellowHuman();
}
public static Human produceBlack() {
return new BlackHuman();
}*/
//第三版 使用反射
public static Human createHuman(Class c) {
Human human = null;
try {
human = (Human) Class.forName(c.getName()).newInstance();
} catch (InstantiationException e) {
System.out.println("顏色");
} catch (IllegalAccessException e) {
System.out.println("人定義錯(cuò)誤");
} catch (ClassNotFoundException e) {
System.out.println("null");
}
return human;
}
}
4. 測試
package com.wanggs.factory;
/**
* Created by wanggs on 2017/7/14.
*/
public class NvWa {
public static void main(String[] args) {
Human human = HumanFactory.createHuman(YellowHuman.class);
human.laugh();
}
}