java反射机制(一)

一.JAVA反射机制:
JAVA反射机制是指在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

二.Class类:
在Java中,每个class都有一个相应的Class对象。也就是说,当我们编写一个类,编译完成后,在生成的.class文件中,就会产生一个Class对象,用于表示这个类的类型信息。
Class类是一切反射的根源。
eg:很多车—>car类
很多人—>person类
很多类—>Class类

三.Class类的应用:

  1. 获得Class对象的3种形式
  2. 调用Class类的默认无参构造方法实例化类对象
  3. 获取所有的构造方法
  4. 获取类属性
  5. 获取类包名与方法

程序Dog类:

public class Dog {
    private String name;
    private int age;
    private String color;

    private String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public Dog() {
    }

    public Dog(String name, int age, String color) {
        this.name = name;
        this.age = age;
        this.color = color;
    }

    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", color='" + color + '\'' +
                '}';
    }
}

1.如何获取Class对象?
①对象.getClass()
②类.class
③Class.forname(类名)

eg1:

     /*
    获取Class对象的三种形式
     */
    @Test
    public void test1() {
        //通过对象的getclass方法(有对象的时候用)
        Dog dog = new Dog("mike", 5, "white");
        Class<? extends Dog> aClass = dog.getClass();   //泛型

        //通过类.class(直到类的时候用)
        Class<Dog> dogClass = Dog.class;

        //通过Class.forname方法(只知道类名字符串时候用)
        try {
            Class<?> aClass1 = Class.forName("com.sihengReflection.Dog");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

2.利用Class类对象实例化Dog类对象,调用了Class类的默认无参构造方法
注:newInstance(): 弱类型。低效率。只能调用无参构造

eg2:

public void test2() {
        Class<Dog> dogClass = Dog.class;
        //通过Class类对象实例化Dog类对象,调用了Class类的默认无参构造方法
        try {
            Dog dog = (Dog) dogClass.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

3.获取所有的构造方法:

eg3:

@Test
    public void test3() {
        Class<Dog> dogClass = Dog.class;//获取类对象
        Constructor<?>[] constructors = dogClass.getConstructors();//获取构造方法集合
        for (int i = 0; i < constructors.length; i++) {
            System.out.println(constructors[i].getName());//方法名称
            System.out.println(constructors[i].getParameterCount());//方法参数个数
        }
        //可以获取有参构造方法的参数数组,constructors[0]是无参的,也可以获取参数数组,不报错
        Class<?>[] parameterTypes = constructors[1].getParameterTypes();
        System.out.println(parameterTypes[0].getName());

        //调用构造方法dogClass.getConstructor获取一个
        try {
            //获取一个特定的构造方法
            Constructor<Dog> constructors1 = dogClass.getConstructor(String.class, int.class, String.class);
            //调用带参数的构造器来实例化对象
            Dog dog = constructors1.newInstance("狗子", 2, "白色");//因为构造方法的实例就是dog对象
            System.out.println(dog.getAge()+"岁");
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

输出:
com.sihengReflection.Dog
0
com.sihengReflection.Dog
3
java.lang.String
2岁

4.获取所有属性:

eg4:

@Test
    public void test4() {
        Class<Dog> dogClass = Dog.class;
        //获取非私有属性
        Field[] fields = dogClass.getFields();
        System.out.println(fields.length);//只能获取到共有属性,所以这里值为零

        //获取所有属性
        Field[] declaredFields = dogClass.getDeclaredFields();//Declared顾名思义,定义了的都可以获取
        System.out.println(declaredFields.length);

        //输出来
        for (int i = 0; i < declaredFields.length; i++) {
            int modifiers = declaredFields[i].getModifiers();//修饰符--->整形--->要强转换
            System.out.println(Modifier.toString(modifiers) + "  " + declaredFields[i].getType() + "  " + declaredFields[i]
                    .getName());
        }
    }

输出:
0
3
private class java.lang.String name
private int age
private class java.lang.String color

5.获取包名与方法:

eg5:

@Test
    public void test5() {
        Dog dog = new Dog("mike", 4, "白色");//先实例化一个Dog对象
        Class<Dog> dogClass = Dog.class;//获取一个类对象
        Package aPackage = dogClass.getPackage();//包
        System.out.println(aPackage.getName());

        //获取共有的方法,包括继承的共有方法
        Method[] methods = dogClass.getMethods();//获取方法

        for (int i = 0; i < methods.length; i++) {
            System.out.println(methods[i]);

            if (methods[i].getName().equals("toString")) {  //利用一下toString()
                try {
                    String s = (String) methods[i].invoke(dog);  //invoke(方法作用的对象,方法参数),这里toString并无参数
                    System.out.println("toString:  "+s);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        }
        System.out.println("--------我是可爱的分割线--------");

        //访问私有方法,6的不行
        Method[] declaredMethods = dogClass.getDeclaredMethods();//获取所有定义了的方法,包括私有方法,但是没有继承(父类的)的方法
        for (int i = 0; i < declaredMethods.length; i++) {
            System.out.println(declaredMethods[i]);   //获取所有定义了的方法
            if (declaredMethods[i].getName().equals("getName")) {
                System.out.println("我可以调用私有方法啦");

                declaredMethods[i].setAccessible(true);//必须设置方法可以访问才可以访问这个私有方法

                try {
                    String name = (String) declaredMethods[i].invoke(dog);
                    System.out.println("我的名字:" + name);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        }
    }

输出:
com.sihengReflection
public java.lang.String com.sihengReflection.Dog.toString()
toString: Dog{name=’mike’, age=4, color=’白色’}
public void com.sihengReflection.Dog.setName(java.lang.String)
public void com.sihengReflection.Dog.setColor(java.lang.String)
public int com.sihengReflection.Dog.getAge()
public void com.sihengReflection.Dog.setAge(int)
public java.lang.String com.sihengReflection.Dog.getColor()
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
——–我是可爱的分割线——–
public java.lang.String com.sihengReflection.Dog.toString()
private java.lang.String com.sihengReflection.Dog.getName()
我可以调用私有方法啦
我的名字:mike
public void com.sihengReflection.Dog.setName(java.lang.String)
public void com.sihengReflection.Dog.setColor(java.lang.String)
public int com.sihengReflection.Dog.getAge()
public void com.sihengReflection.Dog.setAge(int)
public java.lang.String com.sihengReflection.Dog.getColor()

四.总结:
给我的感觉就是反射无视了java的封装。学习反射有利于后续学习java ee时理解框架的原理。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值