反射常用的类对象
Class: 表示所有类
Constructor: 表示所有构造器
Method: 表示所有方法
Field: 表示所有字段
1.创建类的Class的对象
- 方式一:
//方式一:使用class的属性
Class<Date> date1=Date.class;
- 方式二:
//方式二:通过对象中的getClass的方法
Date date = new Date();
Class<?> date2=date.getClass();
- 方式三:
//方式三:通过Class的forName("Class name")静态方法
Class<?> date3=Class.forName("java.util.Date");
创建基本数据类型Class的对象
[byte,short,int,long,float,double,boolea,char,void]都可以通过方法一创建Class的对象
例如:
int.class ,long.class ...void.class
创建数组的Class对象
//方式1: 数组类型.class;
Class<? extends int[]> arr1=int [].class;
//方式2: 数组对象.getClass();
int [] arr=new int[4];
Class<? extends int[]> arr2 = arr.getClass();
2.获取构造器
常用方法:
public Constructor<>[] getConstructors():该方法只能获取当前Class所表示类的public修饰的构造器
public Constructor<>[] getDeclaredConstructors():获取当前Class所表示类的所有的构造器,和访问权限无关
public Constructor<> getConstructor(Class<>… parameterTypes) :获取当前Class所表示类中指定的一个public的构造器
参数:
parameterTypes表示:构造器参数的Class类型的对象
public Constructor<> getDeclaredConstructor(Class<>… parameterTypes) :获取当前Class所表示类中指定的一个的构造
例如下面的代码:
class User{
private User(String name){ }//私有的构造器
public User(){ }
}
--------------------------------------
Class<User> uClz=User.class;
Constructor<User> con1=uClz.getConstructor();
System.out.println(con1);//输出结果:public com.test.fanshe.User()
Constructor<User> con2=uClz.getDeclaredConstructor(String.class);
System.out.println(con2);//输出结果:private com.test.fanshe.User(java.lang.String)
通过构造器创建对象
常用方法:
public T newInstance(Object… initargs):如调用带参数的构造器,只能使用该方式.
参数:
initargs:表示调用构造器的实际参数
返回:返回创建的实例,T表示Class所表示类的类型
例如:
Constructor<User> con2=uClz.getDeclaredConstructor(String.class);//获取构造器
con2.setAccessible(true);//因为构造器的权限是private,所以要设计为可以访问
con2.newInstance("liujun");//通过构造器创建对象,有参数
注意:如果:一个类中的构造器是外界可以直接访问,同时没有参数,那么可以直接使用*Class类中的newInstance方法创建对象.
3.获取方法
Class类中常用方法:
public Method[] getMethods(): 获取包括自身和继承过来的所有的public方法
public Method[] getDeclaredMethods():获取自身类中所有的方法(不包括继承的,和访问权限无关)
public Method getMethod(String methodName,Class<>… parameterTypes):表示调用指定的一个公共的方法(包括继承的)
参数: methodName: 表示被调用方法的名字 parameterTypes:表示被调用方法的参数的Class类型如String.class
public Method getDeclaredMethod(String name,Class<>… parameterTypes):表示调用指定的一个本类中的方法(不包括继承的)
参数:
methodName: 表示被调用方法的名字
parameterTypes:表示被调用方法的参数的Class类型如String.class
例如:
class User{
public User(){}
private void getDate(String date){
System.out.println(date);
}
public static void getStaticDate(String date){
System.out.println(date);
}
}
--------------------------------------
Class<User> uClz=User.class;
Method method1 = uClz.getDeclaredMethod("getDate", String.class);//可以获取到私有的方法
System.out.println(method1);//public void com.test.fanshe.User.getDate(java.lang.String)
Method method2 = uClz.getMethod("getStaticDate", String.class);
System.out.println(method2);//public static void com.test.fanshe.User.getStaticDate(java.lang.String)
使用反射调用方法
常用方法:
public Object invoke(Object obj,Object… args):表示调用当前Method所表示的方法
参数:
obj: 表示被调用方法底层所属对象(调用静态方法的时可以为nul)
Method m = clz.getMethod("liujun",String.class);
args:表示调用方法是传递的实际参数
返回:
底层方法的返回结果
调用私有方法:
在调用私有方法之前:应该设置该方法为可访问的
又因为Method是AccessibleObject子类,所以Method中具有该方法
setAccessible(true);
例如:
class User{
public User(){}
private void getDate(String date){
System.out.println(date);
}
public static void getStaticDate(String date){
System.out.println(date);
}
public void getDates(String... date){
for (String string : date) {
System.out.println(string);
}
}
public void getDates(int... date){
for (int string : date) {
System.out.println(string);
}
}
}
--------------------------------------
Class<User> uClz=User.class;
Method method1 = uClz.getDeclaredMethod("getDate", String.class);//获取方法
method1.setAccessible(true);/设计方法为可访问
method1.invoke(uClz.newInstance(), "liujun1");//调用方法
Method method2 = uClz.getMethod("getStaticDate", String.class);
method2.invoke(null, "liujun2");//调用静态的方法第一个参数可以是null
Method method3 = uClz.getMethod("getDates", int[].class);
method3.invoke(uClz.newInstance(),new Object[]{new int[]{12,23}});//反射调用数组,注意参数的传递方法new Object[]{数组对象}
Method method4 = uClz.getMethod("getDates", String[].class);
method4.invoke(uClz.newInstance(),new Object[]{new String[]{"liu","jun"}});