繼上次的總結,首先說一下如何擷取私有構造函數:
通過反射擷取私有構造函數
Person.java
public class Person {
private String name;
private int age;
public String address;
public Person() {
// TODO Auto-generated constructor stub
}
private Person(String name,int age) {
this.name = name;
this.age = age;
}
public Person(String name, int age, String address) {
this.name = name;
this.age = age;
this.address = address;
}
public void show() {
System.out.println("show........");
}
public void method(String s) {
System.out.println("method "+s);
}
public String getString(String s,int i) {
return s+"==="+i;
}
private void function() {
System.out.println("function");
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", address=" + address + "]";
}
}
測試類:
//不加con.setAccessible(true);報錯:java.lang.IllegalAccessException:非法的通路異常
Constructor con = c.getDeclaredConstructor(String.class,int.class);
con.setAccessible(true);//值為true訓示反射的對象在使用時候取消java語言通路檢查
Object object = con.newInstance("嘿嘿",20);
System.out.println(object);
接下來說一下如何擷取成員變量并進行指派:
Class c = Class.forName("Reflect.Person"); //帶包的全路徑
Field[] fields = c.getFields();
for (Field field : fields) {
System.out.println(field);
}
以上擷取的成員變量隻是public修飾的。
擷取全部的成員變量:
Field[] fields = c.getDeclaredFields(); //擷取全部的變量
for (Field field : fields) {
System.out.println(field);
}
以上兩種方法是擷取全部的變量,接下來說一下如何擷取單個變量并進行使用:
通路公有屬性
//擷取address并對其指派 address是public修飾的
Field addressFiled = c.getField("address");
//通過無參構造方法建立對象
Constructor con = c.getConstructor();
Object obj = con.newInstance();
//addressFiled.set(obj, value):給obj這個對象的addressField這個屬性設定值等于value
addressFiled.set(obj, "濟南");
這個地方的指派比較難了解,addressFiled.set(obj, value);這句代碼的意思是給obj這個對象的addressFiled變量指派為value。
通路私有屬性:
//通路私有的name屬性
Field nameField = c.getDeclaredField("name");
nameField.setAccessible(true);
nameField.set(obj, "張三");
以上是擷取構造器和屬性,還剩擷取所有方法,原理類似于擷取構造器和變量。
擷取公有的方法:
Method[] methods = c.getMethods();//擷取自己的公共方法,包括父類的公共方法
for (Method method : methods) {
System.out.println(method);
}
經過測試發現,裡面的公有方法不僅是Person類裡的公有方法,而且包括Person父類Object裡的公有方法,那如何擷取Person類自身的構造方法呢?
Method[] methods = c.getDeclaredMethods();//擷取自己的所有方法
for (Method method : methods) {
System.out.println(method);
}
接下來是擷取單個方法(這裡分成無參無傳回值、有參無傳回值、有多個參數,有傳回值、和私有方法四個方面來講,這四個方面也基本覆寫了我們類定義的方法)
首先我們構造出無參對象:
Constructor con = c.getConstructor();
Object obj = con.newInstance();
首先看一下擷取無參無傳回值的show()方法:
Method m1 = c.getMethod("show");
m1.invoke(obj);
擷取有參數無傳回值的方法method:
Method m2 = c.getMethod("method", String.class);
m2.invoke(obj, "hello");
取有多個參數的有傳回值得方法getString():
Method m3 = c.getMethod("getString", String.class,int.class);
Object objectString = m3.invoke(obj, "helloworld",);
System.out.println(objectString);
擷取私有方法function():
Method m4 = c.getDeclaredMethod("function");
m4.setAccessible(true);
m4.invoke(obj);
以上就是我們擷取各種方法的步驟,下面我們總結一下:
1.c.getMethod(name, parameterTypes) 第一個參數表示方法名字,第二個參數表示形參的class類型。
2.m1.invoke(obj, args) 第一個參數表示對象是誰,第二個參數表示調用該方法實參。
以上就是反射的基本内容,接下來會舉幾個關于如何利用反射的列子。