java--反射常用方法(三)
一、Class中獲取構造方法
- Constructor類用於描述類中的構造方法:
- Constructor<T> getConstructor(Class<?>... parameterTypes)
返回該Class對象表示類的指定的public構造方法;
- Constructor<?>[] getConstructors()
返回該Class對象表示類的所有public構造方法;
- Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
返回該Class對象表示類的指定的構造方法,和訪問權限無關;
- Constructor<?>[] getDeclaredConstructors()
返回該Class對象表示類的所有構造方法,和訪問權限無關;
Class中獲取構造方法實例
package reflect;
import java.lang.reflect.Constructor;
import java.util.Date;
class Person {
//沒有使用public修飾的類的默認構造器的訪問修飾符是啥?
//一個類的默認的構造器的訪問權限和類的訪問權限一致;
}
public class ConstructorDemo {
public static void main(String[] args) throws Exception {
// 得到Person裏所有公共的構造器
// 先得到Person的字節碼
Class<Dept> clz = Dept.class;
// 獲得Person裏所有public的構造器
Constructor<?>[] cs = clz.getConstructors();//只能獲得公共 的構造器
//Constructor<?>[] cs = clz.getDeclaredConstructors();//所有的構造器
System.out.println(cs.length);
for (Constructor<?> c : cs) {
System.out.println(c);
}
//===========================================
//獲得指定的構造器 protected Dept(int age)
/**
* Constructor<T> getConstructor(Class<?>... parameterTypes)
獲得Class所表示類的指定的public修飾的構造器;
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
獲得Class所表示類的指定的構造器,和訪問權限無關;
*/
//Constructor<Dept> con = clz.getConstructor(int.class);
Constructor<Dept> con = clz.getDeclaredConstructor(int.class);
System.out.println("-->"+con);
//獲得 private Dept()
con = clz.getDeclaredConstructor();
System.out.println(con);
//獲得protected Dept(int age,Date d)
con = clz.getDeclaredConstructor(int.class,Date.class);
System.out.println(con);
}
}
二、Class獲取Method
- Method類用於描述類中的方法:
- Method getMethod(String name, Class<?> ... parameterTypes)
返回該Class對象表示類和其父類的指定的public方法;
- Method[] getMethods():
返回該Class對象表示類和其父類的所有public方法;
- Method getDeclaredMethod(String name, Class<?>... parameterTypes)
返回該Class對象表示類的指定的方法。和訪問權限無關,但不包括繼承的方法;
- Method[] getDeclaredMethods(): 獲得類所有的方法,包括公共、保護、默認(包)訪問和私有方法,但不包括繼承的方法;
Class獲取Method實例
package reflect;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Date;
import java.util.List;
class Sub extends Object {
private void show1() {
}
void show2() {
}
protected void show3() {
}
public void show4() {
}
@Deprecated
public void ooxx(byte[] bys, int age, Integer i1, String name, Date bornDate){}
}
public class MethodDemo {
public static void main(String[] args) throws Exception {
// 得到Object裏所有的public修飾的方法
Class<Sub> clz = Sub.class;
/**
* Method[] getMethods() 得到Class所表示類的所有的public修飾的方法,包括繼承過來的方法 Method[]
* getDeclaredMethods() 和訪問權限無關,不包括繼承過來的的方法
*/
// Method[] ms = clz.getMethods();
Method[] ms = clz.getDeclaredMethods();
for (Method m : ms) {
System.out.println(m);
}
System.out.println("-0--------------------------");
//獲得指定的方法;
/**
* Method getMethod(String methodName, Class<?>... parameterTypes) :public修飾的方法
* Method getDeclaredMethod(String methodName, Class<?>... parameterTypes) 和權限無關,不包括繼承的
*/
//只獲得protected void show3()
Method m = clz.getDeclaredMethod("show3");
System.out.println(m);
//獲得public void ooxx(byte[] bys, int age, Integer i1, String name, Date bornDate)
m = clz.getMethod("ooxx", byte[].class, int.class,Integer.class,String.class,Date.class);
System.out.println(m);
System.out.println(m.getName());
System.out.println(Modifier.toString(m.getModifiers()));
System.out.println(m.getReturnType());
//Arrays: 得到 public static <T> List<T> asList(T... a)
}
}
三、Class中獲取Field
- Field類用於描述類中的字段:
- Field getField(String name)
返回該Class對象表示類和其父類的指定的public字段;
- Field[] getFields()
返回該Class對象表示類和其父類的所有public字段;
- Field getDeclaredField(String name)
返回該Class對象表示類的指定的字段和訪問權限無關,但不包括繼承的字段;
- Field[] getDeclaredFields()
返回當前Class對象中公共、保護、默認(包)訪問和私有字段,但不包括繼承的字段;
Class中獲取Field實例
package reflect;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Date;
class People{
public String name;
}
class Student extends People{
@Deprecated
private int age;
public Date bornDate;
}
public class FieldDemo {
public static void main(String[] args) throws Exception {
Class<Student> clz = Student.class;
/**
* Field[] getFields() : 得到Class所表示類的所有的public修飾的字段,包括繼承的
* Field[] getDeclaredFields() : 得到Class所表示類的所有的字段和訪問權限無關,不包括繼承的
*/
//Field[] fs = clz.getFields();
Field[] fs = clz.getDeclaredFields();
for (Field field : fs) {
System.out.println(field);
}
System.out.println("--------------------------");
/**
* 獲得指定的一個字段:
* Field getField(String filedName) : 得到Class所表示類的所有的public修飾的字段,包括繼承的
* Field getDeclaredField(String fileName) : 得到Class所表示類的所有的字段和訪問權限無關,不包括繼承的
*/
Field f = clz.getDeclaredField("age");
System.out.println(f.toString());
System.out.println(Modifier.toString(f.getModifiers()));
System.out.println(f.getType());
System.out.println(f.getName());
Annotation[] as = f.getDeclaredAnnotations();
for (Annotation a : as) {
System.out.println(a);
}
}
}
四、Class常用方法
package reflect;
import java.io.Serializable;
import java.lang.reflect.Modifier;
import java.util.Date;
import java.util.Map;
@Deprecated//表示過時
class Emp implements Serializable,Comparable<Emp>{
private class A{
}
class B{
}
public int compareTo(Emp o) {
return 0;
}
}
public class ClassCommonMethodDemo {
public static void main(String[] args) {
//獲得Emp類裏的信息//Date
Class<Emp> clz = Emp.class;
/**
* Annotation[] getAnnotations() 返回此元素上存在的所有註釋。
*/
System.out.println(clz.getAnnotations().length);
/**
* Class<?>[] getClasses()
得到Class所描述類的所有的public修飾的內部類
Class<?> getDeclaredClasses()
得到Class所描述類的所有的內部類,和訪問權限無關
*/
//Class<?>[] innerClass = clz.getClasses();
Class<?>[] innerClass = clz.getDeclaredClasses();
System.out.println(innerClass.length);
for (Class<?> c : innerClass) {
System.out.println(c);
}
/**
* Class<?>[] getInterfaces() 確定此對象所表示的類或接口實現的接口。
*/
System.out.println("接口 "+clz.getInterfaces().length);
/**
* int getModifiers() 返回此類或接口以整數編碼的 Java 語言修飾符。
*/
/**
* Modifier:
* static String toString(int mod) 返回描述指定修飾符中的訪問修飾符標誌的字符串。
*/
Class<Date> clzDate = Date.class;
System.out.println(clzDate.getModifiers());//1
System.out.println(Modifier.toString(clzDate.getModifiers()));//public
/**
* String getName() 返回Class所描述類的全限定名
* String getSimpleName() 返回源代碼中給出的底層類的簡稱。
*/
System.out.println(clz.getName());//reflect.Emp
System.out.println(clz.getSimpleName());//Emp
/**
* Package getPackage() 獲取此類的包。
*/
System.out.println(clz.getPackage());
/**
* Class<? super T> getSuperclass()
返回表示此 Class 所表示的實體(類、接口、基本類型或 void)的超類的 Class。
*/
System.out.println("clz.getSuperclass()= " +clz.getSuperclass());
System.out.println(String.class.isArray());//false
System.out.println(String[].class.isArray());//true
System.out.println(Map.class.isInterface());
System.out.println(Gender.class.isEnum());
System.out.println(int[].class.isPrimitive());//
System.out.println(int.class.isPrimitive());
System.out.println(Deprecated.class.isAnnotation());
/**
* <U> Class<? extends U> asSubclass(Class<U> clazz)
強制轉換該 Class 對象,以表示指定的 class 對象所表示的類的一個子類。
*/
Object obj = new Date();
Class<Date> d = (Class<Date>) obj.getClass().asSubclass(Date.class);
System.out.println(d);
/**
* boolean isInstance(Object obj)
判定指定的 Object 是否與此 Class 所表示的對象賦值兼容。
對象 instanceof 類
*/
System.out.println("-->"+obj.getClass());//Date d = new Date();
boolean b = Object.class.isInstance(new Date());
System.out.println(b);//true
System.out.println(Date.class.isInstance(obj));
}
}
五、Class創建對象
創建對象:
- 使用Class對象的newInstance()方法創建該Class對象的實例,此時該Class對象必須要有無參數的構造方法。
- 使用Class對象獲取指定的Constructor對象,再調用Constructor的newInstance()方法創建對象類的實例,此時可以選擇使用某個構造方法。
創建對象實例
package reflect;
import java.lang.reflect.Constructor;
import java.util.Date;
class Teacher{
private Teacher(String name){
System.out.println(name);
}
public String toString() {
return "老師";
}
}
public class NewInstanceDemo {
public static void main(String[] args) throws Exception {
// Teacher t = new Teacher();
//System.out.println(t);
/**使用反射來創建對象
* 1.
* public T newInstance():只能創建非private,無參的構造方法的對象;好比 new 類();
* T classInstance.newIntance();
* 如同用一個帶有一個空參數列表的 new 表達式實例化該類。如果該類尚未初始化,則初始化這個類。
*
* 2.
* 1>.先得到一個指定的構造方法,
* 2>.調用構造器裏的一個方法,
* T newInstance(Object... initargs) 、
* initargs表示構造器的需要的實際參數
*/
Class<Teacher> clz = Teacher.class;
//Teacher t2 = clz.newInstance();
//System.out.println(t2);
// System.out.println(t == t2);//false
//調用有參的私有構造方法
Constructor<Teacher> con = clz.getDeclaredConstructor(String.class);
/**
* 訪問私有的成員之前:先設置其爲可訪問的
*
* AccessibleObject: 表示可訪問的對象,是Contructor,Method,Filed的父類;
* 方法: void setAccessible(boolean flag) :用來設置是否可訪問的
若要設置可訪問的:
obj.setAccessible(true);
*/
con.setAccessible(true);//設置可訪問的
Teacher t = con.newInstance("will");
System.out.println(t);
//===========================
System.out.println("------------------");
createInstance();
}
//使用反射來創建java.util.Date的對象
public static void createInstance() throws Exception{
//new Date();
Class<?> clz = Class.forName("java.util.Date");
Date d = (Date) clz.newInstance();
System.out.println(d);
//
Constructor<Date> con = (Constructor<Date>) clz.getConstructor();
System.out.println(con.newInstance());
//new Date(long time);
con = (Constructor<Date>) clz.getConstructor(long.class);
System.out.println(con.newInstance(1));
}
}