反射【框架設(shè)計(jì)的靈魂】:將類的各個組成部分封裝為其他對象,這就是反射機(jī)制
好處:1.可以在程序運(yùn)行過程中,操作這些對象
2.?可以解耦,提高程序的可拓展性
獲取class對象的3種方式:
1.Class.forname(“全類名”);將字節(jié)碼文件加載進(jìn)內(nèi)存,返回Class對象【多用于配置文件,將類名定義在配置文件中。讀取對象,加載類】
2.類名.class:通過類名的屬性class獲取【多用于參數(shù)的傳遞】
3.對象.getClass:該方法在object中定義【多用于對象獲取字節(jié)碼的方式】
同一字節(jié)碼文件(*.class)在一次程序運(yùn)行中,只會被加載一次,不論通過哪一種 方式獲取到的Class對象都是同一個
?
?
Class對象功能
獲取功能:
1.獲取成員變量們
Field getField(String name)
Field[] getFields() 獲取所有public修飾的成員變量
Field getDeclaredField(String name)
Field[] getDeclaredFields() 獲取所有成員變量
?
Field方法
Object get(Object obj) ?【獲取值】
void set(Object obj, Object value) 【設(shè)置傳入對象值】
?
setAccessible(true)【暴力反射】?忽略訪問權(quán)限修飾符的安全檢查
?
2.獲取構(gòu)造方法們
Constructor<T> getConstructor(類<?>... parameterTypes)
Constructor?con=personClass.?getConstructor(String.class,int.class)
Constructor<?>[] getConstructors()
Constructor<T> getDeclaredConstructor(類<?>... parameterTypes) ?
Constructor<?>[] getDeclaredConstructors() ?
?
Constructor
【創(chuàng)建對象】
1.T newInstance(Object... initargs) ?
con.newInstance(“張三”,”23”)
2.如果使用空參構(gòu)造方法創(chuàng)建對象,操作可以簡化:Class對象的 newInstance方法
personClass.newInstance()
3.獲取成員方法們
Method getMethod(String name, 類<?>... parameterTypes) ??
Method[] getMethods() ?
Method?getDeclaredMethod(String name, 類<?>... parameterTypes)
Method[] getDeclaredMethods()
?
Method
執(zhí)行方法
Object invoke(Object obj, Object... args) ?【第一個參數(shù)是類對象】
4.獲取全類名
String getName()
返回單位名稱(類,接口,數(shù)組類,原始類型,或無效)的 類對象表示,作為一個 String。
??
創(chuàng)建一個配置文件pro.properties?
className=cn.itcast.domin.Person
methodName=eat
1.加載配置文件
(1)?創(chuàng)建Properties對象 ??Properties p= new Properties();
(2)??加載配置文件,轉(zhuǎn)換為一個集合 ?
獲取class目錄下的配置文件
ClassLoder classloader=ReflectTest.class.getClassLoader();[獲得該字節(jié)碼文件的類加載器]
IntputSteam is=Classloader.getResourceAsStream(“pro.properties”);[獲取資源所對應(yīng)的字節(jié)流]
pro.load(i);
2.獲取配置文件中定義的數(shù)據(jù)
String ?className = pro.getProperty(“className”);
String ?className = pro.getProperty(“methodName”);
3.加載該類進(jìn)內(nèi)存
Class ?cls = Class.forName(className);
4.創(chuàng)建對象
Object obj=cls.newInstance();
5.獲取方法對象
Method method=cls.getMethod(methodName);
6.執(zhí)行方法
method.invoke(obj);
?
【jvm記載類順序測試】
package edu.xupt.reflect;
public class Demo1 { static { System.out.println("main方法將被執(zhí)行"); }
public static void main(String[] args) throws ClassNotFoundException { System.out.println(Son.z);
} } class Father{ static { System.out.println("父類靜態(tài)代碼塊"); } public Father() { System.out.println("父類初始化"); } static int f=100; } class Son extends Father{ static { System.out.println("子類靜態(tài)代碼塊"); z=200; } static int z=100; static final int N=1000; public Son() { System.out.println("子類初始化"); } }
package edu.xupt.reflect;
public class Demo2 { public static void main(String[] args) throws ClassNotFoundException { System.out.println("獲取系統(tǒng)類的加載器"); ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); System.out.println(systemClassLoader); System.out.println("獲取系統(tǒng)類加載器的父加載器-->拓展加載器"); ClassLoader parent = systemClassLoader.getParent(); System.out.println(parent); System.out.println("獲取拓展類加載器的父加載器-->根加載器"); ClassLoader parent1 = parent.getParent(); System.out.println(parent1); System.out.println(Demo2.class.getClassLoader()); Class<?> aClass = Class.forName("edu.xupt.reflect.Demo2"); System.out.println(aClass.getClassLoader());
System.out.println("檢測JDK內(nèi)置類是誰加載的"); System.out.println(Object.class.getClassLoader()); System.out.println(Class.forName("java.lang.ClassLoader" /*Object*/).getClassLoader());
System.out.println("獲得系統(tǒng)類加載器可以加載的路徑"); System.out.println(System.getProperty("java.class.path")); /* D:\Java\jdk1.8.0_212\jre\lib\charsets.jar; D:\Java\jdk1.8.0_212\jre\lib\deploy.jar; D:\Java\jdk1.8.0_212\jre\lib\ext\access-bridge-64.jar; D:\Java\jdk1.8.0_212\jre\lib\ext\cldrdata.jar; D:\Java\jdk1.8.0_212\jre\lib\ext\dnsns.jar; D:\Java\jdk1.8.0_212\jre\lib\ext\jaccess.jar; D:\Java\jdk1.8.0_212\jre\lib\ext\jfxrt.jar; D:\Java\jdk1.8.0_212\jre\lib\ext\localedata.jar; D:\Java\jdk1.8.0_212\jre\lib\ext\nashorn.jar; D:\Java\jdk1.8.0_212\jre\lib\ext\sunec.jar; D:\Java\jdk1.8.0_212\jre\lib\ext\sunjce_provider.jar; D:\Java\jdk1.8.0_212\jre\lib\ext\sunmscapi.jar; D:\Java\jdk1.8.0_212\jre\lib\ext\sunpkcs11.jar; D:\Java\jdk1.8.0_212\jre\lib\ext\zipfs.jar; D:\Java\jdk1.8.0_212\jre\lib\javaws.jar; D:\Java\jdk1.8.0_212\jre\lib\jce.jar; D:\Java\jdk1.8.0_212\jre\lib\jfr.jar; D:\Java\jdk1.8.0_212\jre\lib\jfxswt.jar; D:\Java\jdk1.8.0_212\jre\lib\jsse.jar; D:\Java\jdk1.8.0_212\jre\lib\management-agent.jar; D:\Java\jdk1.8.0_212\jre\lib\plugin.jar; D:\Java\jdk1.8.0_212\jre\lib\resources.jar; D:\Java\jdk1.8.0_212\jre\lib\rt.jar; D:\Java\zhang\2019.11.23—注解\out\production\2019.11.23—注解; D:\IntelliJ IDEA 2019.2.3\lib\idea_rt.jar
*/
} }
【反射基本方法測試】
package edu.xupt.reflect;
import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method;
public class Demo3 { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException { Class<?> c1 = Class.forName("edu.xupt.reflect.Student");
System.out.println("類名"); System.out.println(c1.getName()); System.out.println(c1.getSimpleName()); System.out.println("======================"); System.out.println("獲得成員變量"); Field[] fields = c1.getFields(); for (Field field : fields) { System.out.println(field); } fields = c1.getDeclaredFields(); for (Field field : fields) { System.out.println(field); } System.out.println("======================"); Method[] methods = c1.getMethods(); for (Method method : methods) { System.out.println(method); } System.out.println(">>>>>>>>>>>>>>>>>>>>"); methods = c1.getDeclaredMethods(); for (Method method : methods) { System.out.println(method); } System.out.println("======================"); Constructor<?> constructor = c1.getConstructor(int.class, String.class, boolean.class); System.out.println(constructor); Class<String> stringClass = String.class; System.out.println(stringClass); } }
class Student{ private int id; private String name; private boolean sex; // public String name1;
public Student() { }
public Student(int id, String name, boolean sex) { this.id = id; this.name = name; this.sex = sex; }
public Student(int id) { this.id = id; }
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getName() { return name; }
public String setName(String name) { return this.name = name; } private void show(){ System.out.println("show被調(diào)用"); } public void show1(){ System.out.println("show1被調(diào)用"); }
public boolean isSex() { return sex; }
public void setSex(boolean sex) { this.sex = sex; }
@Override public String toString() { return "Student{" "id=" id ", name='" name '\'' ", sex=" sex '}'; } }
【單例模式的反射破壞】
package edu.xupt.desidn.singleton;
import java.awt.geom.FlatteningPathIterator; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException;
public class Demo6 { public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException { /* test1 test = new test1(); for (int i = 0; i < 100; i ) { new Thread(test).start(); }*/ Constructor<Singleton6> Constructor = Singleton6.class.getDeclaredConstructor(null); Constructor.setAccessible(true); Singleton6 singleton6 = Constructor.newInstance(); Field flag = Singleton6.class.getDeclaredField("flag"); flag.setAccessible(true); flag.set(singleton6,false); Singleton6 singleton61 = Constructor.newInstance(); System.out.println(singleton6 == singleton61); } } class Singleton6{ private static boolean flag= false; private volatile static Singleton6 singleton6;
private Singleton6() {//[可以考慮直接拋異常,不允許進(jìn)構(gòu)造] if (flag==false){ flag=true; System.out.println("第一次進(jìn)構(gòu)造");} else {throw new RuntimeException("不要想著用反射破壞我的單例"); } }
public static Singleton6 getSingleton6() { if (singleton6==null){ synchronized (Singleton6.class){ if (singleton6==null){ System.out.println("實(shí)例化"); singleton6 = new Singleton6(); } } } return singleton6; } } class test6 implements Runnable{ @Override public void run() { Singleton6.getSingleton6(); } }
?
來源:https://www./content-4-596151.html
|