Table of Contents
1.4:Class對象.getSuperclass()獲取到父類
1:.getDeclaredConstructors():獲取所有的構造方法
1:getDeclaredMethods():獲取所有的方法對象,包括私有的和實現接口的,但不包括父類的;
3:.getMethod():獲取public的方法包括父類的和實現接口的
相信很多人都知道反射可以說是Java中最強大的技術了,它可以做的事情太多太多,很多優秀的開源框架都是通過反射完成的,比如最初的很多註解框架,後來因爲java反射影響性能,所以被運行時註解APT替代了,java反射有個開源框架jOOR相信很多人都用過,不過我們還是要學習反射的基礎語法,這樣才能自己寫出優秀的框架,當然這裏所講的反射技術,是學習Android插件化技術、Hook技術等必不可少的!
1:創建Class
1.1: getClass方法
String str = "Hello";
Class aClass = str.getClass();
System.out.println(""+aClass.getName());//java.lang.String
User user = new User();
Class calss2 = user.getClass();
System.out.println(""+calss2.getName());//com.wkl.bean.User
1.2:Class.forName
try {
//這裏也通過捕獲異常,因爲我們傳的這個字符串可能不合法,字符串合法命名是類的命名空間和類的名稱組成
Class<?> aClass = Class.forName("java.lang.String");
System.out.println(""+aClass.getName());//java.lang.String
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
1.3:類名.class
Class<User> userClass = User.class;
System.out.println(""+userClass.getName());//com.wkl.bean.User
1.4:Class對象.getSuperclass()獲取到父類
Class<?> aClass = Class.forName("java.lang.String");
System.out.println(""+aClass.getName());//java.lang.String
String name = aClass.getSuperclass().getName();
System.out.println(""+name);//java.lang.Object
2:獲取構造方法
當類中方法定義爲私有的時候我們能調用?不能!當變量是私有的時候我們能獲取嗎?不能!但是反射可以,比如源碼中有你需要用到的方法,但是那個方法是私有的,這個時候你就可以通過反射去執行這個私有方法,並且獲取私有變量。
public class User {
private String name;
private int age;
private String sex;
public User(String name) {
this.name = name;
}
public User(String name, int age) {
this.name = name;
this.age = age;
}
private User(int age) {
this.age = age;
}
}
1:.getDeclaredConstructors():獲取所有的構造方法
Class<User> userClass = User.class;
Constructor<?>[] constructors = userClass.getDeclaredConstructors();
for (Constructor<?> constructor : constructors) {
System.out.println(constructor);
System.out.println("構造器名稱:"+constructor.getName());
System.out.println("修飾符類型:"+constructor.getModifiers());
Parameter[] parameters = constructor.getParameters();
System.out.println("構造器參數:"+ JSONArray.toJSONString(parameters));
Class<?>[] parameterTypes = constructor.getParameterTypes();
System.out.println("構造器參數類型:"+ JSONArray.toJSONString(parameterTypes));
System.out.println("=====================================================");
}
2:getConstructors():獲取共有的構造方法
其餘的和上邊一樣
3:獲取特定的構造方法
我們可以通過getDeclaredConstructor()方法傳參獲取特定參數類型的構造方法,
這裏注意是getDeclaredConstructor()不是 getDeclaredConstructors() ,所以返回的是一個Class對象而不是一個Class數組。
Class<User> userClass = User.class;
try {
Constructor<User> declaredConstructor = userClass.getDeclaredConstructor(String.class);
System.out.println(""+declaredConstructor);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
不傳參數,默認取無參構造方法
4:利用構造方法反射創建對象
Class<User> userClass = User.class;
try {
Constructor<User> declaredConstructor = userClass.getDeclaredConstructor(String.class);
System.out.println(""+declaredConstructor);
User user = declaredConstructor.newInstance("123");
System.out.println(""+user);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
結果:
5:調用類的私有構造方法
調用私有構造方法呢,和上面一樣,只是我們要設置constructors.setAccessible(true);
3:對類中方法的操作
1:getDeclaredMethods():獲取所有的方法對象,包括私有的和實現接口的,但不包括父類的;
Class<User> userClass = User.class;
Method[] declaredMethods = userClass.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println("方法名:"+declaredMethod.getName());
System.out.println("修飾符"+declaredMethod.getModifiers());
System.out.println("參數類型:"+JSONArray.toJSONString(declaredMethod.getParameterTypes()));
System.out.println("返回類型:"+declaredMethod.getReturnType());
System.out.println("================");
}
方法名:toString
修飾符1
參數類型:[]
返回類型:class java.lang.String
================
方法名:moth2
修飾符2
參數類型:[]
返回類型:class java.lang.String
================
方法名:moth1
修飾符1
參數類型:[]
返回類型:class java.lang.String
================
2:getDeclaredMethod():獲取指定方法
第一個參數是方法名,第二個參數是參數類型
Class<User> userClass = User.class;
try {
//第一個參數是方法名,第二個參數是參數類型
Method meth1 = userClass.getDeclaredMethod("moth1",String.class);
System.out.println(""+ JSONObject.toJSONString(meth1));
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
3:.getMethod():獲取public的方法包括父類的和實現接口的
Method meth1 = userClass.getMethod("moth1",String.class);
4:meth1.invoke():指定特定的方法
invoke需要兩個參數一個是類的實例,一個是方法參數。
Class<User> userClass = User.class;
try {
User user = new User("aa");
//第一個參數是方法名,第二個參數是參數類型
Method meth1 = userClass.getDeclaredMethod("moth1",String.class);
Object wkl = meth1.invoke(user, "wkl");
System.out.println(""+wkl);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
wkl:moth1
4:通過Field類,爲對象設置字段值
Class<User> userClass = User.class;
Field name = userClass.getDeclaredField("name");
User user = userClass.newInstance();
//因爲屬性是私有的,所以需要設置Accessible
name.setAccessible(true);
name.set(user,"wkl");
System.out.println(""+user);
User{name='wkl', age=0, sex='null'}