1、什么是反射
反射是java语言的一种机制,利用反射机制动态的实例化对象(构造函数)、读写属性、调用方法。
2、类类
获取全路径类名有三种方法
1.Class.forName(类的全限定名)
2.对象名.getClass
3.类名.Class
另外,获取全限定名的方法:类名.getName()
获取类名的方法:类名.getSimpleName()
获取包名的方法:类名.getPackage()
3.反射实例化
根据类得到类构造的方法
1.获取单个公有构造方法:class.getConstrutor();
2.获取单个构造方法(包括私有、受保护、默认、公有):class.getDeclaredConstrutor();
3.获取所有的公有构造方法:class.getConstrutors();
4.获得所有构造方法(包括私有、受保护、默认、公有):class.getDeclaredConstructors();
如果是有参构造,需要在括号里写上参数类型
反射实例化对象的方法
class.newInstance();
如果方法为私有的,需要打开访问权限:setAccessible(true);
package com.fs;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
public class Demo3 {
public static void main(String[] args) throws Exception {
Class c = Class.forName("com.fs.Student");
System.out.println(c);
//反射实例化对象调用无参构造
Student stu =(Student) c.newInstance();
//构造器对象
Constructor con1 = c.getDeclaredConstructor();
Object new1 = con1.newInstance();
System.out.println(new1);
//两个参数的构造方法
Constructor con2 = c.getDeclaredConstructor(String.class,String.class);
Object new2 = con2.newInstance("aaa","s002");
System.out.println(new2);
//私有的方法
Constructor con3 = c.getDeclaredConstructor(Integer.class);
//打开访问权限
con3.setAccessible(true);
Object new3 = con3.newInstance(33);
System.out.println(new3);
}
}
4.反射动态方法调用
1.获取单个公有方法:class.getMethod();
2.获取单个方法(包括私有、受保护、默认、公有):class.getDeclaredMethod();
3.获取所有的公有方法:class.getMethods();
4.获得所有方法(包括私有、受保护、默认、公有):class.getDeclaredMethods();
括号第一个参数为方法名,如果方法有参数,第二个参数为传参类型
调用方法:invote(对象名,有参传值)
package com.fs;
import java.lang.reflect.Method;
public class Demo4 {
public static void main(String[] args) throws Exception {
Class<?> c = Class.forName("com.fs.Student");
System.out.println(c);
//实例化对象
Student s=(Student) c.newInstance();
//无参方法
Method m1 = c.getDeclaredMethod("hello");
//调用方法
m1.invoke(s);
//有参方法
Method m2 = c.getDeclaredMethod("hello",String.class);
m2.invoke(s, "sa");
//调用两个参数的方法
Method m3 = c.getDeclaredMethod("add", Integer.class,Integer.class);
//放行
m3.setAccessible(true);
Object invoke = m3.invoke(s, 4,4);
System.out.println(invoke);
}
}
5.反射读写属性
首先需要获得属性名:Field field=cla.getField(“属性名”);
获取属性名:field.getName();
获取属性类型:filed.getType();
设置属性值,参数1:要设置属性所在对象;参数2:要设置的值:field.set(Object,Object);
获取属性值,参数:要获取属性值的对象:field.get(Object);
获取单个属性(私有、公有、受保护、默认、静态):class.getDeclaredField(“属性名”);
获取所有属性(私有、公有、受保护、默认、静态):class.getDeclaredFields();
Class c = Class.forName("com.fs.Student");
System.out.println(c);
//反射实例化对象调用无参构造
Student stu =(Student) c.newInstance();
//反射读写属性
Field field = c.getDeclaredField("sid");
//打开访问限制
field.setAccessible(true);
//反射修改属性
field.set(stu, "s001");
field.get(stu);
6.属性访问修饰符
获得访问修饰符的方法:field.getModifiers();
Field field1 = c.getDeclaredField("age");//age属性为public
int modifiers = field1.getModifiers();
System.out.println(modifiers);
System.out.println(Modifier.FINAL);
System.out.println(Modifier.PUBLIC);
控制台
于是,我验证了以下
public 1 private 2
final 16 static 8
这样我们就可以根据访问修饰符知道属性的访问控制