反射
反射机制是在【运行状态】中:
对于任何一个类,都能知道该类的所有属性与方法;
对于任何一个对象,都能调用它的任意一个方法与属性;
反射提供的功能:
1、在运行时判断任意对象所属的类;
2、在运行时构建任意类的对象;
3、在运行时判断任意类所具有的成员变量与方法‘
4、在运行时调用任意对象的方法;
5、生成动态代理
反射方法详解:
public class rTest {
public static void main(String[] args) throws Exception {
/*获得反射对象(反射入口),即class对象,有三种方法:
1、Class,forName(全类名)
2、XXX.class // Class c2= animal.class;
3、对象.getClass()
//animal a= new animal();
// Class c3= a.getClass();
*/
System.out.println("A-----获得反射对象(反射入口),即class对象");
Class c1 = Class.forName("reflectTest.animal");
System.out.println(c1);
System.out.println("------------------------");
System.out.println("B-----获得无参构造器");
Constructor constructor= c1.getConstructor();
System.out.println("C-----利用构造器,创建对象实例");
animal a1 = (animal) constructor.newInstance();
System.out.println(a1.sayName());//实例调用方法
System.out.println("D-----(有参构造函数)--加载类、反射类的构造函数、利用构造函数new一个Animal实例instance--");
//类型.class;基本类型与包装类不一样
Constructor constructor2= c1.getConstructor(String.class,int.class);
animal a2 = (animal) constructor2.newInstance("Cat",20);
System.out.println("E-----获得本类中的所有的字段(属性)(无视修饰符) -------------------------");
Field[] fields = c1.getDeclaredFields();
for (Field field : fields) {
System.out.println(field);//无需取得权限
}
for (Field field : fields) {
System.out.println("反射时,如果因为修饰符限制报错,修改private属性需要权限,可使用XXX.setAccessible(true)");
field.setAccessible(true);
System.out.println(field + ", 字段值 = " + field.get(a1));
}
System.out.println("F-----获得类中的所有的公有字段(属性)(包括父类)(public)--------------------");
fields = c1.getFields();
for (Field field : fields) {
System.out.println(field + ", 字段值 = " + field.get(a1));
// 如果,字段名称等于"name",且字段类型为String,我们就修改字段的值,也就是类中变量name的值
if (field.getName() == "name" && field.getType().equals(String.class)) {
System.out.println("------F.1----属性可通过XXX.set进行修改(注意,原值在类中name=\"Dog\"");
String newname = (String) field.get(a1);// 记得转换一下类型
newname = "哈士奇";// 重新给name赋值
System.out.println("field是方法,a1是对象,newname是值,设置当前实例a1的name值,使修改后的值生效");
field.set(a1, newname);
}
}
System.out.println("---------修改后的name = " + a1.name);
System.out.println("G-------获取本类中的所有的方法(无视修饰符)--------------------");
Method[] methods= c1.getDeclaredMethods();
for (Method m:methods
) {
System.out.println(m);
}
System.out.println("H-------获取本类中的所有的公有方法,包括子类、父类中和实现接口中的所有public方法-----------");
methods= c1.getMethods();
for (Method m:methods) {
System.out.println(m);
}
System.out.println("I-------根据方法名称和参数类型获取指定方法,并唤起方法:指定所属对象a1,并给对应参数赋值------");
Method getSay = c1.getMethod("sayName");
System.out.println("-------I.1--反射中,方法的调用使用----方法名.invoke(对象,参数)---实现");
System.out.println(getSay.invoke(a1,null));
System.out.println("J-------获取所有接口");
Class[] interFaces = c1.getInterfaces();
for (Class c:interFaces
) {
System.out.println(c.toString());
}
System.out.println("K-------越过泛型约束(不提倡)");
ArrayList<Integer> listInteger= new ArrayList<>();
listInteger.add(1232);//只能添加Integer类型数据
Class listclass= listInteger.getClass();//获取list的class(反射入口)
Method methodAdd= listclass.getMethod("add",Object.class);//获取add方法,参数设为object类型
methodAdd.invoke(listInteger,"not Integer");
System.out.println(listInteger.toString());
}
}
public class animal implements animalInterface1{
public String name = "Dog";
private int age=30;
public animal() {
System.out.println("animal无参构造器");
}
public animal(String name, int age) {
this.name = name;
this.age = age;
System.out.println(name+","+age);
}
public String sayName() {
return "hello"+name;
}
@Override
public void interface1() {
System.out.println("interface1..get...lalalala");
}
}