一、步骤
创建类的对象:调用Class对象的newInstance()方法
所需:
- 类必须有一个无参构造方法
- 类的构造方法的访问权限要够
注意:
没有无参构造器也可以创建对象
步骤:
- 通过Class类的getDeclaredConstructor(Class … parameterTypes)取得本类指定形参类型的构造器。
- 向构造器的形参中传递一个对象数组进去,里面包含了构造器中所需的各个参数。
- 实例化newInstance(Object … initargs)
1 | public void test(){ |
二、通过反射调用类的完整结构
类的结构:
- 实现的全部接口
- 所继承的父类
- 全部的构造器
- 全部的方法
- 全部的属性
1.获取运行时类的属性1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23Class clazz=Student.class;
//1.getFields();只能获取运行时类中及其父类中声明为public的属性
Field[] fields=clazz.getFields();
for(int i=0;i<fields.length;i++){
System.out.println(fields[i]);
}
//2.getDeclaredFields();获取运行时类本身声明的所有属性
Field[] fields1=clazz.getDeclaredFields();
//foreach
for(Field f:fileds1){
System.out.println(f.getName());
//2.1获取每个属性的权限修饰符
int i=f.getModifiers();
String str=Modifier.toString(i);
System.out.print(str+" ");
//2.2获取属性的类型
Class type=f.getType();
System.out.print(type.getName()+" ");
//2.3获取属性名
System.out.println(f.getName());
}
2.获取运行时类的方法1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52public void test(){
Class clazz=Student.class;//获取运行时类Student类对象
//1.getMethods()获取运行时类及其父类中所有的声明为public的方法
Method[] m1=clazz.getMethods();
for(Method m:m1){
System.out.println(m);
}
//2.getDeclaredMethods():获取运行时类本身声明的所有的方法
Method[] m2=clazz.getDeclaredMethods();
for(Method m:m2){
System.out.println(m);
}
}
public void test1(){
Class clazz=Student.class;
Method[] m1=clazz.getDeclaredMethods();
//1.获取注解
Annotation[] ann=m.getAnnotations();
for(Method m:m1){
System.out.println(m);
for(Annotation a:ann){
System.out.println(a);
}
}
//2.获取方法的权限修饰符
String str=Modifier.toString(m.getModifiers());
System.out.print(str+" ");
//3.获取方法的返回值类型
Class returnType=m.getReturnType();
System.out.print(returnType.getName()+" ");
//4.获取方法名
System.out.print(m.getName());
//5.获取方法的形参列表
System.out.print("(");
Class[] params=m.getParameterTypes();
for(int i=0;i<params.length;i++){
System.out.print(params[i].getName()+" args-"+i+" ");
}
System.out.print(")");
//6.获取异常类型
Class[] exps=m.getExceptionTypes();
for(int i=0;i<exps.length;i++){
System.out.println(exps[i].getName());
}
}
3.获取构造方法1
2
3
4
5
6
7
8public void test(){
String className="pers.zx.test.Student";
Class clazz=Class.forName(className);
Constructor[] cons=clazz.getDeclaredConstructors();
for(Constructor c: cons){
System.out.println(c);
}
}
4.获取其他1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50//1.获取运行时类的父类
public void test(){
String className="pers.zx.test.Student";
Class clazz=Class.forName(className);
Class superClass=clazz.getSuperclass();
System.out.println(superclass);
}
//2.获取带泛型的父类
public void test(){
String className="pers.zx.test.Student";
Class clazz=Class.forName(className);
Type type=clazz.getGenericSuperclass();
System.out.println(type);
}
}
//3.获取父类的泛型是什么类型
public void test(){
String className="pers.zx.test.Student";
Class clazz=Class.forName(className);
Type type=clazz.getGerericSuperclass();
ParameterizedType param=(ParameterizedType)type;//强转成参数
Type[] args=param.getActualTypeArguments();//获取参数,用数组接收
for(Type t:args){
System.out.println(((Class)t).getName());//由于Type继承Class,这时强转就是向下转型,来获取参数名称
}
}
//4.获取实现的接口
public void test(){
Class clazz=Student.class;
Class[] interfaces=clazz.getInterfaces();
for(Class i:interfaces){
System.out.println(i);
}
}
//5.获取所在的包
public void test(){
Class clazz=Student.class;
Package p=clazz.getPackage();
System.out.println(p);
}
//6.获取注解
public void test(){
Class clazz=Student.class;
Annotation[] anns=clazz.getAnnotations();
for(Annotation a:anns){
System.out.println(a);
}
}
注意:java.lang.reflect 反射机制
三、通过反射调用类中的指定方法、指定属性
1.获取指定属性1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20public void test(){
Class clazz=Student.class;
//1.获取指定的属性--通过属性名
//getField()获取运行时类中指定名为public的
//getDeclaredField获取任意的
Field name=clazz.getField("name");
//2.创建运行时类的对象---实例化
Student s=(Student)clazz.newInstance();
System.out.println(s);
//3.将运行时类指定的属性赋值,
name.set(s,"zx");//给对象s的name属性赋值zx
System.out.println(s);
//对于私有属性
Field age=clazz.getDeclaredField("age");
age.setAccessible(true);//设置可访问
age.set(s,20);
System.out.println(s);
}
}
2.获取指定方法1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21public void test(){
Class clazz=Student.class;
//getMechod(方法名,Class ... params)
Method m=clazz.getMethod("display");//display是方法名
//由于调用方法需要对象,所以要实例化一个对象
Student s=(Student)clazz.newInstance();
//invoke(对象,参数)参数即方法参数
Object obj=m.invoke(s);//根据返回值调用
System.out.println(obj);
//调用静态方法,由于静态方法没有对象也可以调用
Method m2=clazz.getMethod("staticMethod);
m2.invoke(Student.class);//直接类名.class调用
//调用私有方法,带参数 privateMethod(String s,Integer i)
Method m3=clazz.getDeclareMethod("privateMethod",String.class,Integer.class);
m3.setAccessible(true);
Object obj1=m3.invoke(s,"zx",10);
System.out.println(obj1);
}
3.调用指定的构造器1
2
3
4
5
6
7
8
9
10
11public void test(){
//把它看成向上转型,这个clazz调用Class中的方法,
//而下面的强制转换是到student类中,调用该类的方法
Class clazz=Student.class;
Constructor cons=clazz.getDeclaredConstructior(String.class,int.class);
cons.setAccessible(true);
//具体到Student类的实例化,从而调用student类的方法
Student s=(Student)cons.newInstance("zx",20);
System.out.println(s);
}