java反射中属性,方法,构造器


反射:1.给定的一个类,通过反射获取到这个类(class)对象所有成员结构

    2.给定一个具体的对象,能够动态地调用它的方法及对任意属性值进行获取和赋值

Boy类

public class Boy extends Person {

    public int height;

    private int weight;

    public static String description;

    public Boy() {}

    private Boy(int height) {
        this.height = height;
    }

    public Boy(int height, int weight) {
        this.height = height;
        this.weight = weight;
    }

    public static void playBasketball() {
        System.out.println("play basketball!");
    }

    public static void playBall(String ballType) {
        System.out.println("play " + ballType + "!");
    }

    private void pickUpGirl() {
        System.out.println("pick up girl!");
    }

    public int getWeight() {
        return weight;
    }

    public int getHeight() {
        return height;
    }
}

"获取类的方法"

 public static void main(String[] args) throws  Exception{
        Class clazz= Boy.class;
        Class<?>  clazz1 = new Boy().getClass();
        Class<?> clazz2 = Main.class.getClassLoader().loadClass("com.tuling.jvm.reflect.Boy");
        Class<?> clazz3 =Class.forName("com.tuling.jvm.reflect.Boy");
        System.out.println(clazz);
        System.out.println(clazz2);
        System.out.println(clazz3);
        System.out.println(clazz1);
    }

 输出结果

 

Filed字段属性

常用的方法

Field[] fields = clazz.getFields(); // 获取类中所有的公有字段
Field[] declaredFields = clazz.getDeclaredFields(); // 获取类中定义的字段
Field nameField = clazz.getField("name"); // 获取指定名称的公有字段
Field declaredField = clazz.getDeclaredField("likeDesc"); // 获取指定名称类中定义的字段
int modifiersField = likeDescField.getModifiers(); // 获取字段的修饰
nameField.setAccessible(true); // 指定字段强制访问
nameField.set(person, "hncboy"); // 成员字段赋值(需指定对象)
descriptionField.set(null, "hncboy"); // 静态字段赋值

方法演示

 public static void main(String[] args) throws  Exception{
        Class clazz= Boy.class;
        //指定类中所有公有字段,包含继承的
        Field[] fields = clazz.getFields();
        for (Field field:fields){
            System.out.println(field.toString());
        }
        //获取到指定的属性
        Field field = clazz.getField("name");
        System.out.println(field);
        //指定类中的所有字段,包含私有的,不包括继承
        Field [] declaredMethods  = clazz.getDeclaredFields();
        for(Field declare:declaredMethods){
           System.out.println(declare.toString());
        }
        // 获取本类中指定名称类中定义的字段
        Field weightField = clazz.getDeclaredField("weight");
        //将各字段设置为共有访问
        System.out.println(weightField);
        Boy  boy = clazz.newInstance();
        weightField.setAccessible(true);
        weightField.set(boy,20);
        System.out.println(boy.getWeight());
        //静态字段赋值,静态字段不需要指定对象
        Field descField = clazz.getField("description");
        descField.set(null,"静态属性");
        System.out.println(Boy.description);
    }

输出

Method方法

常用的方法

Method[] methods = clazz.getMethods(); // 获取类中所有的公有方法
Method[] declaredMethods = clazz.getDeclaredMethods(); // 获取本类的所有方法
Method talkMethod = clazz.getMethod("talk", String.class); // 获取类中指定名称和参数的公有方法
Method pugMethod = clazz.getDeclaredMethod("pickUpGirls"); // 获取本类中定义的指定名称和参数的方法
int modifiers = pugMethod.getModifiers(); // 获取方法的修饰符
talkMethod.invoke(boy, "I tell you"); // 指定对象进行成员方法的调用
pugMethod.setAccessible(true); // 指定方法的强制访问
pickUpGirlsMethod.invoke(null); // 指定静态方法的调用

方法演示

  public static void main(String[] args) throws  Exception{
        Class clazz = Boy.class;
        Method[] methods = clazz.getMethods();
        for (Method method:methods){
            System.out.println(method);
        }
        //无参数
        Method talkMethod = clazz.getMethod("talk");
        System.out.println(talkMethod.getName());
        //获取类中指定的方法有参
        Method playMethod = clazz.getMethod("playBall",String.class);
        System.out.println(playMethod.getName());
        //获取本类中的所有方法,不包含继承,包含私有
        Method[] declaredMethods = clazz.getDeclaredMethods();
        for (Method method:declaredMethods){
            System.out.println(method);
        }
        Method declaredMethod = clazz.getDeclaredMethod("pickUpGirl");
        System.out.println(declaredMethod.getName());
        //底层是基于无参数构造器
        Boy boy = clazz.newInstance();
        playMethod.invoke(boy,"足球");
        declaredMethod.setAccessible(true);
        declaredMethod.invoke(boy);
        //调用静态方法
        Method playBasketBall = clazz.getDeclaredMethod("playBasketball");
        playBasketBall.invoke(null);
    }

输出结果 

注意一般要完成方法的调用都需要先有对象实例,然后方法里面调用invoke

 构造器

常用方法

Constructor<?>[] constructors = clazz.getConstructors(); // 获取类中所有的公有构造器
Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors(); // 获取类中所有的构造器
Constructor<?> declaredConstructor = clazz.getDeclaredConstructor(); // 获取类中无参的构造器
Constructor<?> constructor = clazz.getDeclaredConstructor(String.class, String.class); // 获取类中有参构造器
int modifiers = constructor.getModifiers(); // 获取构造器的修饰符
declaredConstructor.newInstance(); // 构造器实例对象
declaredConstructor.setAccessible(true); // 指定构造器的强制访问
constructor.newInstance("hncboy"); // 有参构造调用
clazz.newInstance(); // 直接调用默认无参构造

方法演示

   public static void main(String[] args) throws  Exception{
        Class clazz = Boy.class;
        //获取所有类中的公有的办法
        Constructor<?>[] constructors = clazz.getConstructors();
        for (Constructor<?> constructor:constructors){
            System.out.println(constructor);
        }
        //获取类中所有的构造器,包含私有的
        Constructor<?>[]  declaredConstructor = clazz.getDeclaredConstructors();
        for (Constructor<?> constructor:declaredConstructor){
            System.out.println(constructor);
        }
        //获取类中无参的构造器
        Constructor<?> noParamsConstructor = clazz.getDeclaredConstructor();
        System.out.println(noParamsConstructor);
        Constructor<?>constructor1= clazz.getDeclaredConstructor(int.class);
        Constructor<?>constructor2= clazz.getDeclaredConstructor(int.class,int.class);
        System.out.println(noParamsConstructor.getModifiers());
        System.out.println(constructor1.getModifiers());
        System.out.println(constructor2.getModifiers());
        //调用构造器
        Boy boy = (Boy) noParamsConstructor.newInstance();
        System.out.println(boy);
        constructor1.setAccessible(true);
        boy = (Boy)constructor1.newInstance(17);
        System.out.println(boy.getHeight());
    }

输出结果

 至此关于反射的 属性 方法 构造器完成,

总结:构造器构造,方法的调用,属性的赋值

相关