目录
1.反射的概念
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为的Java语言的反射机制。
2.反射实现的功能
①在运行时判断任意一个对象所属的类;
②在运行时构造任意一个类的对象;
③在运行时判断任意一个类所具有的成员变量和方法;
④在运行时调用任意一个对象的方法;
⑤生成动态代理。
3.反射的要点
- 反射是发生在程序的运行期间
- 在类加载的时候,在内存中就会存在一个这个类的类对象,对象中存在这个类的所有信息(方法,属性,构造器...)
- 在创建的对象的时候,得到的是这个类对象的一个镜像|复制体
- 如果拿到了类型类类的实例,就可以进行一切操作
4.获取类对象|源头
- 类名的的.class
- 对象.getClass()
- 的Class.forName(“包名+类名”); ----最推荐
public static void main(String[] args) throws ClassNotFoundException {
//test("Apple");
//1.类名.class
Class ref=RefletDemo07.class;
System.out.println(ref.getName());
RefletDemo07 ref2=new RefletDemo07();
//2.2.对象.getClass()
Class<?> r=ref2.getClass();
System.out.println(r);
//3.Class.forName("包名+类名");
Class<?> r2=Class.forName("reflect.RefletDemo07");
System.out.println(r2);
}
static void test(String str) throws ClassNotFoundException{
if("Apple".equals(str)){
// new Apple();
Class.forName("com.relect.Apple");
}else{
// new Banana(); //香蕉
Class.forName("com.relect.Banana");
}
}
5.获取构造器
- Contrustor getContrustor(Class ...);获取公共的指定的构造器。
- Contrustor [] getContrustors();获取公共的所有的构造器。
- 构造函数<T> getDeclaredConstructor(Class <?> ... parameterTypes)获取指定的某个构造器。
- Constructor [] getDeclaredConstructors()获取所有的构造器(包括私有)。
public class ReflectDemo08{
private String name;
public static void main(String[] args) throws NoSuchMethodException, SecurityException {
//1.获取 Class对象
Class ref=ReflectDemo08.class;
//获取指定的公共股构造
/*Constructor con=ref.getConstructor(String.class);
System.out.println(con);*/
//获取所有公共的构造器
Constructor[] cons=ref.getConstructors();
for(Constructor c:cons){
System.out.println(c);
}
//获取指定的私有构造器
Constructor con2=ref.getDeclaredConstructor();
System.out.println(con2);
//获取所有的私有构造器
Constructor[] con2s=ref.getDeclaredConstructors();
for(Constructor c:con2s){
System.out.println(c);
}
}
private ReflectDemo08() {
// TODO Auto-generated constructor stub
}
private ReflectDemo08(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
6.获取方法
- 方法getMethod(方法名,Class <?> ... parameterTypes); 获取公共的指定的方法
- 方法[] getMethods(); 获取公共的所有的方法
- 方法<T> getDeclaredMethod(方法名,Class <?> ... parameterTypes)获取指定的某个方法
- Method [] getDeclaredMethods()获取所有的方法(包括私有)
- 方法对象.invoke(类型的对象,参数);
注意:
如果在本类中正常使用。
如果外类中使用私有的,需开放权限:setAccessible(false) - > true(放开)默认false(关闭)
public static void getMethods() throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException{
Class cls=Class.forName("reflect.ReflectDemo10");
ReflectDemo10 ref=(ReflectDemo10) cls.newInstance();
Method[] methods= cls.getDeclaredMethods();
for(Method m:methods){
System.out.println(m); //获取方法名名字 是所有修饰符代表数字的和
}
// methods[2].invoke(ref, "周杰伦");
// methods[3].invoke(ref);
//methods[4].invoke(ref);
//其他类中私有的方法
Class c=Person.class;
Person ref1=(Person) c.newInstance();
Method m=c.getDeclaredMethod("test");
//打开权限
m.setAccessible(true);
m.invoke(ref1);
Method m2=c.getDeclaredMethod("testStatic");
m2.invoke(null);
}
7.获取属性|字段
- Field getField(字段名字); 获取公共的指定的字段
- Field [] getFields(); 获取公共的所有的字段
- Field <T> getDeclaredField(字段名字)获取指定的某个字段
- Field [] getDeclaredFields()获取所有的字段(包括私有)
- 字段对象.SET(对象,字段值);
- 字段对象获得(对象);
注意:
如果在本类中正常使用。
如果外类中使用私有的,需开放权限:setAccessible(false) - > true(放开)默认false(关闭)
private static void getField() throws ClassNotFoundException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, InstantiationException{
Class cls=Class.forName("reflect.ReflectDemo10"); //权限定名=包名+类名
ReflectDemo10 ref=(ReflectDemo10) cls.newInstance();
Field[] fields=cls.getDeclaredFields();
for(Field f:fields){
System.out.println(f.getModifiers()); //获取字段名名字,是所有修饰符代表数字的和
}
fields[0].set(ref, "haha");
//ref.setName("hehe");
System.out.println(fields[0].get(ref));
System.out.println(ref.getName());
/*Field f=cls.getField("age");
f.set(ref, "10");
System.out.println(ref.age);*/
//使用Person类中的私有的属性
Class c=Person.class;
Person ref1=(Person) c.newInstance();
Field f=c.getDeclaredField("gender");
f.setAccessible(true);
f.set(ref1, 1);
f.get(ref1);
//打开权限
f.setAccessible(false);
//关闭权限
System.out.println(f.isAccessible());
}
8.获取父类的|父接口的的类对象
- 子类的类对象.getSuperclass() - 单个 获得父类的Class对象
- 子类的类对象.getInterfaces() - 数组 获得父类接口的Class对象
//2.获取父类|父接口的Class对象
public static void getFu() throws ClassNotFoundException, InstantiationException, IllegalAccessException{
//1.获取类的Class对象 调用方法 newInstance() 创建对象 调用空构造 空构造一般都给
Class ref=Class.forName("reflect.ReflectDemo09");
Class clsFu=ref.getSuperclass();
//2.创建对象调用方法
Fu fu=(Fu) clsFu.newInstance();
fu.test();
Class[] cls=ref.getInterfaces();
for(Class cl:cls){
System.out.println(cl);
}
}
9.创建类型对象根据类对象
Class对象.newInstance()--->调用空构造
获取构造器
构造器对象.newInstance(Class <?> ... parameterTypes);注意: newInstance()是调用空构造,如果空构造不存在,会出现异常。由此可知,使用其他构造器创建对象比较麻烦,所以确保空构造存在。
//获取源头
Class<?> clz = Class.forName("com.shsxt.ref.simple.User");
//第一种:通过newInstance()创建对象
User user=(User)clz.newInstance();
user.setUname("sxt");
user.setUpwd("good");
//第二种:通过getDeclaredConstructors()创建对象,取得全部构造函数(注意顺序)
Constructor<?>[] cons=clz.getDeclaredConstructors();
for(Constructor<?>c:cons){
System.out.println(c);
}
// 注意观察上面的输出结果,再实例化,否则参数容易出错
User u1=(User)cons[0].newInstance("shsxt","good");
User u2=(User)cons[1].newInstance("sxt");
User u3=(User)cons[2].newInstance();
System.out.println(u1.getUname()+u1.getUpwd());
10.修饰符
类对象|方法对象|构造器对象|字段对象.getModifiers();
得到修饰符代表数字的和。
//3.,获取修饰符
static void getMo() throws ClassNotFoundException{
//1.获取类的Class对象 调用方法 newInstance() 创建对象 调用空构造 空构造一般都给
Class ref=Class.forName("reflect.ReflectDemo09");
int i=ref.getModifiers();
System.out.println(i);
}