java反射

    科技2024-10-02  25

    反射

    可以操作.class字节码文件。

    获得字节码文件

    Class.forName(包名.文件名);对象.getClass();类.class; //第一种,如果只需要运行一个类的静态代码块,可以用Class.forName() Class c1=Class.forName("base.反射.HelloWorld"); HelloWorld helloWorld=new HelloWorld(); //第二种 Class c2=helloWorld.getClass(); //第三种 Class c3 = HelloWorld.class; //三个值相同,说明是c1==c2==c3 System.out.println(c1.hashCode());//460141958 System.out.println(c2.hashCode());//460141958 System.out.println(c3.hashCode());//460141958

    常用方法

    getName()(获取完整类名,包括包名)getSimpleName()(获取简单类名,只有类名)getField(字段名)(获取相应的字段名,只有public)getFields()(获取所有的字段名,只有public)getDeclaredFields()(获取所有的字段,无视范围) public class HelloWorld { public int no=1; String describe="qwe"; protected double size=3.14; private int id=5; private String name="zhangsan"; private double area=1234; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getArea() { return area; } public void setArea(double area) { this.area = area; } public HelloWorld() { System.out.println("Hello,World!"); } public HelloWorld(int id) { this.id = id; } public HelloWorld(int id, String name) { this.id = id; this.name = name; } public HelloWorld(int id, String name, double area) { this.id = id; this.name = name; this.area = area; } void run() { System.out.println("开始跑"); } public void run(int i) { System.out.println("跑了"+i+"米"); } protected void go() { } int num(int n) { return n; } @Override public String toString() { return "HelloWorld{" + "no=" + no + ", describe='" + describe + '\'' + ", size=" + size + ", id=" + id + ", name='" + name + '\'' + ", area=" + area + '}'; } }

    重点:获取属性的值

    //通过反射获取字段名、字段类型、字段值、字段权限修饰符 Class world=Class.forName("base.反射.HelloWorld"); //调用无参的构造方法 Object o = world.newInstance(); //获取完整类名 System.out.println(world.getName());//base.反射.HelloWorld //获取简单类名 System.out.println(world.getSimpleName());//HelloWorld //获取指定字段名,只能是public Field id = world.getField("no"); System.out.println(id.getName());//no // id.set(o,5); //获取id的值 System.out.println(id.get(o)); //获取所有字段名,只能是public Field[] fields = world.getFields();// for (Field f:fields){ System.out.println(f.getName());//no public只有一个 } System.out.println("==========="); //获取所有字段名,无视范围 Field[] declaredFields = world.getDeclaredFields(); for(Field f2:declaredFields){ //打破封装,造成安全问题 f2.setAccessible(true); //获取字段的权限修饰符 System.out.print(Modifier.toString(f2.getModifiers())+" "); //获取字段的类型 System.out.print(f2.getType().getSimpleName()+" "); System.out.print(f2.getName()+" = ");//可获取所有的字段名 //f2.get(o)方法,可以获取对象o中的f2的值,但不能获取private的,只有打破封装后才能获得私有的值 System.out.println(f2.get(o)); } //public int no = 1 // String describe = qwe //protected double size = 3.14 //private int id = 5 //private String name = zhangsan //private double area = 1234.0 getDeclaredMethod()(获取所有的方法,无视范围)

    重点:调用方法

    //通过反射获取方法,调用 Class c1 = Class.forName("base.反射.HelloWorld"); //调用无参的构造方法 Object o = c1.newInstance(); //获取方法,run() 方法是通过方法名和参数列表识别的。 Method m1=c1.getDeclaredMethod("run"); //调用run()方法 Object invoke = m1.invoke(o); //获取方法,run(int i) Method m2=c1.getDeclaredMethod("run",int.class); //调用run(int i)方法 Object invoke1 = m2.invoke(o, 67); //获取m1权限修饰符 System.out.print(Modifier.toString(m1.getModifiers())+" "); //获取m1返回值 System.out.print(m1.getReturnType()+" "); //获取m1方法名 System.out.println(m1.getName()); //获取m2权限修饰符 System.out.print(Modifier.toString(m2.getModifiers())+" "); //获取m2返回值 System.out.print(m2.getReturnType()+" "); //获取m2方法名 System.out.println(m2.getName()); //获取m2的参数列表的类型 Class[] parameterTypes = m2.getParameterTypes(); for(Class f:parameterTypes){ System.out.println(f.getSimpleName()); } //在创建对象时会执行无参的构造方法 //Hello,World! //开始跑 //跑了67米 // void run //public void run //int getDeclaredConstructor()(获取构造方法) //通过反射创建对象 Class c1 = Class.forName("base.反射.HelloWorld"); //获取无参的构造方法,构造方法考参数列表区分 Constructor declaredConstructor = c1.getDeclaredConstructor(); //创建无参的对象 Object o1 = declaredConstructor.newInstance(); System.out.println(o1); //获取HelloWorld(int id)方法 Constructor declaredConstructor1 = c1.getDeclaredConstructor(int.class); //创建带一个参数的对象 Object o2 = declaredConstructor1.newInstance(7); System.out.println(o2); //Hello,World! //HelloWorld{no=1, describe='qwe', size=3.14, id=5, name='zhangsan', area=1234.0} //HelloWorld{no=1, describe='qwe', size=3.14, id=7, name='zhangsan', area=1234.0}
    Processed: 0.010, SQL: 8