Java反射機(jī)制:是指在運(yùn)行時(shí)去獲取一個(gè)類的變量和方法信息,然后通過(guò)獲取到的信息來(lái)創(chuàng)建對(duì)象,調(diào)用方法的一種機(jī)制。由于這種動(dòng)態(tài)性,可以極大的增強(qiáng)程序的靈活性,程序不用在編譯期就完成確定,在運(yùn)行期仍然可以擴(kuò)展。
獲取Class類的對(duì)象我們要想通過(guò)反射去使用一個(gè)類,首先我們要獲取到該類的字節(jié)碼文件對(duì)象,也就是類型為Class類型的對(duì)象
這里我們介紹三種方式獲取Class類型的對(duì)象
Student類
public class Student {private String name;
int age;
public String address;
public Student() {}
private Student(String name) {this.name = name;
}
Student(String name,int age) {this.name = name;
this.age = age;
}
public Student(String name, int age, String address) {this.name = name;
this.age = age;
this.address = address;
}
private void function() {System.out.println("function");
}
public void method1 () {System.out.println("method");
}
public void method2 (String s) {System.out.println("method" + s);
}
public String method3 (String s, int i) {return s + "," + i;
}
@Override
public String toString() {return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", address='" + address + '\'' +
'}';
}
}
測(cè)試反射類
public class ReflectTest {public static void main(String[] args) throws ClassNotFoundException {// 使用類的class屬性來(lái)獲取該類對(duì)應(yīng)的Class對(duì)象
Classc1 = Student.class;
Classc2 = Student.class;
System.out.println(c1);
System.out.println(c1 == c2);// true
System.out.println("==========");
// 調(diào)用對(duì)象的getClass()方法,返回該對(duì)象所屬類對(duì)應(yīng)的Class對(duì)象
Student s = new Student();
Class extends Student>c3 = s.getClass();
System.out.println(c1 == c3);// true
System.out.println("==========");
// 使用Class類中的靜態(tài)方法forName(String className)
Class>c4 = Class.forName("com.example.fanshe.Student");
System.out.println(c1 == c4);// true
}
}
反射獲取構(gòu)造方法并使用public class ReflectTest {public static void main(String[] args) {// 得到Student類的字節(jié)碼文件對(duì)象
ClassstudentClass = Student.class;
Constructor>[] constructors = studentClass.getConstructors();
for (Constructor>con : constructors) {System.out.println(con);
}
}
}
public class ReflectTest {public static void main(String[] args) {// 得到Student類的字節(jié)碼文件對(duì)象
ClassstudentClass = Student.class;
Constructor>[] constructors = studentClass.getDeclaredConstructors();
for (Constructor>con : constructors) {System.out.println(con);
}
}
}
public class ReflectTest {public static void main(String[] args) throws NoSuchMethodException,
InvocationTargetException, InstantiationException, IllegalAccessException {// 得到Student類的字節(jié)碼文件對(duì)象
ClassstudentClass = Student.class;
// 拿到無(wú)參公共構(gòu)造方法
Constructorconstructor = studentClass.getConstructor();
// 使用反射方式創(chuàng)建對(duì)象
Student student = constructor.newInstance();
System.out.println(student);
}
}
public class ReflectTest {public static void main(String[] args) throws NoSuchMethodException,
InvocationTargetException, InstantiationException, IllegalAccessException {ClassstudentClass = Student.class;
// 拿到無(wú)參公共構(gòu)造方法
//Constructorconstructor = studentClass.getConstructor();
// 拿到3個(gè)參數(shù)的構(gòu)造方法
Constructorconstructor = studentClass.getConstructor(String.class,
int.class, String.class);
// 使用反射方式創(chuàng)建對(duì)象
Student student = constructor.newInstance("小米", 19, "廣東");
System.out.println(student);
}
}
基本數(shù)據(jù)類型同樣可以通過(guò)class屬性得到對(duì)應(yīng)的Class類型
newInstance()方法:創(chuàng)建反射類對(duì)應(yīng)的類的實(shí)例
public class ReflectTest {public static void main(String[] args) throws NoSuchMethodException,
InvocationTargetException, InstantiationException, IllegalAccessException {// 得到Student類的字節(jié)碼文件對(duì)象
ClassstudentClass = Student.class;
// 拿到指定構(gòu)造函數(shù)
Constructorconstructor = studentClass.getDeclaredConstructor(String.class);
// 取消訪問(wèn)檢查,以便使用私有構(gòu)造方法創(chuàng)建對(duì)象
constructor.setAccessible(true);
Student student = constructor.newInstance("小米");
System.out.println(student);
}
}
public void setAccessible(boolean flag)
這個(gè)方法用于取消訪問(wèn)檢查,暴力反射機(jī)制
Class類方法 | 說(shuō)明 |
---|---|
public Field[] getFields() | 返回所有公共字段數(shù)組 |
public Field[] getDeclaredFields() | 返回所有字段數(shù)組 |
public Field getField(String name) | 返回指定公共字段 |
public Field getDeclaredField(String name) | 返回指定字段 |
public class ReflectTest {public static void main(String[] args) throws NoSuchMethodException,
InvocationTargetException, InstantiationException,
IllegalAccessException, NoSuchFieldException {// 得到Student的字節(jié)碼對(duì)象
ClassstudentClass = Student.class;
// 得到address字段
Field addressField = studentClass.getDeclaredField("address");
// 得到name字段
Field nameField = studentClass.getDeclaredField("name");
// 得到無(wú)參構(gòu)造方法
Constructorconstructor = studentClass.getConstructor();
// 創(chuàng)建對(duì)象
Student student = constructor.newInstance();
// 取消訪問(wèn)檢查
nameField.setAccessible(true);
// 為字段設(shè)置值
addressField.set(student, "西安");
nameField.set(student, "小米");
// 打印
System.out.println(student);
}
}
public void set(Object obj, Object value)
為字段設(shè)置值
參數(shù)說(shuō)明:
Class類方法 | 說(shuō)明 |
---|---|
public Method[] getMethods() | 返回所有公共方法數(shù)組(包含繼承過(guò)來(lái)的) |
public Method[] getDeclaredMethods() | 返回所有方法數(shù)組(不包含繼承的) |
public Method getMethod(String name, Class>… parameterTypes) | 返回指定的公共方法 |
public Method getDeclaredMethod(String name, Class>… parameterTypes) | 返回指定的方法 |
public class ReflectTest {public static void main(String[] args) throws NoSuchMethodException,
InvocationTargetException, InstantiationException,
IllegalAccessException {// 得到Student的字節(jié)碼對(duì)象
ClassstudentClass = Student.class;
// 得到method1方法
Method method = studentClass.getDeclaredMethod("method1");
// 得到method2方法
Method method2 = studentClass.getMethod("method2", String.class);
// 得到method3方法
Method method3 = studentClass.getMethod("method3", String.class, int.class);
// 得到function方法
Method function = studentClass.getDeclaredMethod("function");
// 得到公共的無(wú)參構(gòu)造方法
Constructorconstructor = studentClass.getConstructor();
Student student = constructor.newInstance();
// 調(diào)用方法
method.invoke(student);
method2.invoke(student, "s");
Object s = method3.invoke(student, "s", 1);
System.out.println(s);
function.setAccessible(true);
function.invoke(student);
}
}
public Object invoke(Object obj, Object... args)
調(diào)用方法
參數(shù)說(shuō)明:
Class類方法 | 說(shuō)明 |
---|---|
public< A extends Annotation >A getAnnotation(Class< A >annotationClass) | 獲取指定的注解信息 |
public class ReflectTest {public static void main(String[] args) throws NoSuchMethodException,
InvocationTargetException, InstantiationException,
IllegalAccessException, NoSuchFieldException {ArrayListarrays = new ArrayList<>();
Class extends ArrayList>aClass = arrays.getClass();
Method add = aClass.getMethod("add", Object.class);
add.invoke(arrays, "word");
System.out.println(arrays);
}
}
需求二:通過(guò)配置文件運(yùn)行類中的指定方法public class ReflectTest {public static void main(String[] args) throws NoSuchMethodException,
InvocationTargetException, InstantiationException,
IllegalAccessException, ClassNotFoundException, IOException {// 加載數(shù)據(jù)
Properties prop = new Properties();
FileReader fr = new FileReader("src\\main\\java\\com\\example\\fanshe\\class.properties");
prop.load(fr);
fr.close();
String className = prop.getProperty("className");
String methodName = prop.getProperty("methodName");
// 得到字節(jié)碼文件對(duì)象
Class>aClass = Class.forName(className);
// 得到無(wú)參構(gòu)造方法
Constructor>constructor = aClass.getConstructor();
// 創(chuàng)建對(duì)象
Object o = constructor.newInstance();
// 得到method1方法
Method method1 = aClass.getMethod(methodName);
// 調(diào)用方法
method1.invoke(o);
}
}
class.properties文件如下:
className=com.example.fanshe.Student
methodName=method1
需求三,使用注解替代配置文件@MyAnnotation(className = "com.example.fanshe.Student",methodName = "method1")
public class ReflectTest {public static void main(String[] args) throws NoSuchMethodException,
InvocationTargetException, InstantiationException,
IllegalAccessException, ClassNotFoundException, IOException {// 通過(guò)注解來(lái)運(yùn)行指定類中的指定方法
ClassreflectTestClass = ReflectTest.class;
MyAnnotation annotation = reflectTestClass.getAnnotation(MyAnnotation.class);
String className = annotation.className();
String methodName = annotation.methodName();
// 得到字節(jié)碼文件對(duì)象
Class>aClass = Class.forName(className);
// 得到無(wú)參構(gòu)造方法
Constructor>constructor = aClass.getConstructor();
// 創(chuàng)建對(duì)象
Object o = constructor.newInstance();
// 得到method1方法
Method method1 = aClass.getMethod(methodName);
// 調(diào)用方法
method1.invoke(o);
}
}
注解定義如下:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {String className();
String methodName();
}
這就是框架常用到的技術(shù)了,后期在談到框架時(shí)我們?cè)谏钊胗懻摚敲唇裉炀拖鹊竭@里了
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧