反射:java反射就是在运行状态中,对于任意一个类,都能够获取这个类的所有属性和方法;
反射原理: 动态访问对象
具体实现:
//将一个类Test加载到内存中
Class cls = class.forName("Test类全路径");
//调用Test类里全部方法
Method[] mm1 = cls.getDeclaredMethods();
//查看Test类中所有方法
for(Method mmw:mm1){
//带有路径
System.out.println(mmw);
//只是名字
System.out.println(mmw.getName());
}
//查看Test类中可直接调用的方法,[不含私有方法 ,含有父类共有方法]
Method[] mm2 = cls.getMethods();
for(Method mmw1:mm2){
System.out.println(mmw1);
}
//创建Test类对象
Object obj = cls.newIntance();
//调用Test类里set方法
Method m1 = cls.getDeclaredMethod("set方法名" 类型[String].class);
//private修饰的方法 要修改可访问性 访问(会让private失效)
m1.setAccessible(true);
//获取参数个数
int count = m1.getParameterCount();
System.out.print(count);
//参数类型
Class[] clss = m1.getParameterTypes();
for(Class ccc:clss){
System.out.println(ccc.getName());
}
//调用
m1.invoke(obj,"血雨探花");
//调用get方法
Method m2 = cls.getDeclaredMethod("get方法名");
//查看get方法返回类型
Class cc1 = m2.getReturnType();
//精准匹配 ==
//模糊匹配 instance of
if(cc1 == String.class){
System.out.println("是String类型");
}else{
System.out.println("不是String类型");
}//调用 等价于java里的obj.getname();
String name = m2.invoke(obj);
System.out.println(name); //血雨探花//变长参数[动态数组]
//语法:参数类型... 参数名
public static void Test1(List<String> list,String... arr){
for(String ss1:arr){
list.add(ss1);
}
System.out.println(ss1+" : "+ss1.size());
}
变长参数(动态数组)
----------------------
语法: 数据类型... 变量名
特点:
1,要求所有参数类型必须一致
2,动态数组参数必须是形参列表的最后一个参数
3,一个形参列表中只能含有一个动态数组
反射常用类
---------------------
Class: 不能new, 类描述符(描述一个其它类),图纸
获取一个类的描述信息(类描述符,class对象)
1,Class.forName("com.reflect.day01.Person");
2,类名.class Person.class
3,对象名.getClass();
Method: 方法类,方法描述符,描述一个方法
Modifier: 修饰符类
Field : 字段描述符(属性描述符)
Constructor: 构造描述符
cls == int.class 数据类型匹配(精准匹配)
模糊匹配 对象名 instanceof 数据类型