Java基础复习反射

什么是反射

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

Class对象

Java的三大特性是继承、封装和多态。

相同的两个类之间的共性的部分可以抽取成一个父类,比如男人和女人可以抽取成父类人,因为男人和女人都有共性,吃饭,喝水这样的动作,和手脚这样的属性。

同样的不同的 .class文件中也有共性的,比如方法,字段,构造函数。
所以 .class文件向上抽取就成了 Class类


/**
*	Person类
*
*/
public class Person {

    public String name;
    private Integer age;
    Person(){

    }
    Person(String name,Integer age){
        this.name=name;
        this.age=age;
    }

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

    public void show(){
        System.out.println(this.toString());
    }

    private void privateMethod(){
        System.out.println("我是私有的方法");
    }
}


获取Class对象的三种方式

  1. 获取字节码对象的方式
  2. 根据类中的静态属性来获取
  3. 根据类的静态方法getClass来获取需要传入一个类的全限定名(该字符串参数的值是某个类的全限定名(必须添加完整包名))

public static void get() throws ClassNotFoundException {
        /**
         * 获取Class对象的三种方式
         */
        /*
         * 获取字节码对象的方式:
         * 1,Object类中的getClass()方法的。
         * 想要用这种方式,必须要明确具体的类,并创建对象。
         * 麻烦 .
         *
         */
        Person p=new Person();
        Class<? extends Person> aClass = p.getClass();
        /*
         * 方式二:
         * 2,任何数据类型都具备一个静态的属性.class来获取其对应的Class对象。
         * 相对简单,但是还是要明确用到类中的静态成员。
         * 还是不够扩展。
         */
        Class<Person> personClass = Person.class;

        /*
         * 方式三:
         * 只要通过给定的类的 字符串名称就可以获取该类,更为扩展。
         * 可是用Class类中的方法完成。
         * 该方法就是forName.
         * 这种方式只要有名称即可,更为方便,扩展性更强。
         */
        Class<?> aClass1 = Class.forName("com.company.Person");
        System.out.println(aClass1);


    }

获取Class中的构造函数并创建对象

  1. 通过空参的构造器创建对象(没有空构造器会抛出异常)
  2. 通过获取构造器来创建对象 .getStructure()

/**
     * 获取构造函数
     */
    public static void getStructure() throws Exception {

        //第一步要获取Class对象
        Class<?> ac = Class.forName("com.company.Person");
        //通过空参的构造器创造对象
//        Person o = (Person) ac.newInstance();

        //构造器也是一个对象,获取构造器,通过构造器获取对象
        Constructor constructor = ac.getConstructor(String.class, Integer.class);
        Person zyn = (Person) constructor.newInstance("zyn", 22);
        System.out.println(zyn.getName());

    }

获取Class中的字段

  1. 获取public修饰的 .getField(String name)c
  2. 获取本类的字段,但包含私有。 .getDeclaredField(String name); //传入的是字段名
  3. 对私有字段的访问取消权限检查。暴力访问。(只有对私有字段设置了取消权限检查才可以访问)

/**
     *  获取字段
     */
    public static void getField() throws Exception {

        //第一步还是先获取Class对象
        Class<?> aClass = Class.forName("com.company.Person");
        //获取构造函数
        Constructor<?> constructor = aClass.getConstructor(String.class, Integer.class);
        //创建对象
        Person p = (Person) constructor.newInstance("zhangsan",25);
        //字段也是一个对象,获取字段
        Field name = aClass.getField("name");
        //字段的赋值,需要告诉给哪个对象,赋什么值
        name.set(p,"zyn");
        //字段的获取值,需要传入获取哪个字段的值
        String strName = (String) name.get(p);


        //获取本类中的字段,但包含私有
        Field age = aClass.getDeclaredField("age");
        //对私有字段的访问取消权限检查。暴力访问。,只有对私有字段设置了取消权限检查才可以访问
        age.setAccessible(true);


        System.out.println(age.get(p));
        System.out.println(strName);

    }

获取Class中的方法

  1. 获取所有方法
  2. 获取本类中的方法(包含私有)
  3. 方法的执行(私有的方法想要使用也是设置取消访问权限)

/**
     * 获取方法
     */
    public static void getMethod() throws Exception {
        //第一步获取Class对象
        Class<?> aClass = Class.forName("com.company.Person");
        //创建对象
        Constructor<?> constructor = aClass.getConstructor(String.class, Integer.class);
        Person zyn = (Person) constructor.newInstance("zyn", 21);
        //方法也是对象(获取所有共有的方法)
        Method[] methods = aClass.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }
        //获取本类中所有的方法,包含私有
        Method[] declaredMethods = aClass.getDeclaredMethods();

        //获取本类中的方法
        aClass.getMethod("show",null);//第一个参数串方法名,空参就传入null,非空参
        //获取本类中私有的方法
        Method privateMethod = aClass.getDeclaredMethod("privateMethod", null);
        //私有的方法想要使用也是设置取消访问权限
        privateMethod.setAccessible(true);
        //执行方法也是需要知道执行哪个对象的改方法
        privateMethod.invoke(zyn);//如果有参数就穿进去参数就可以了

        Method show = aClass.getMethod("show", String.class);
        show.invoke(zyn,"123456");


    }

API使用说明

获取构造函数

//获取构造方法
/*
 * 通过Class对象可以获取某个类中的:构造方法;
 *
 * 获取构造方法:
 *         1).批量的方法:
 *             public Constructor[] getConstructors():所有"公有的"构造方法
              public Constructor[] getDeclaredConstructors():获取所有的构造方法(包括私有、受保护、默认、公有)
 *         2).获取单个的方法,并调用:
 *             public Constructor getConstructor(Class... parameterTypes):获取单个的"公有的"构造方法:
 *             public Constructor getDeclaredConstructor(Class... parameterTypes):获取"某个构造方法"可以是私有的,或受保护、默认、公有;
 *
 *             调用构造方法:
 *             Constructor-->newInstance(Object... initargs)
 */

获取成员函数


/*
 * 获取成员方法并调用:
 *
 * 1.批量的:
 *      public Method[] getMethods():获取所有"公有方法";(包含了父类的方法也包含Object类)
 *      public Method[] getDeclaredMethods():获取所有的成员方法,包括私有的(不包括继承的)
 * 2.获取单个的:
 *      public Method getMethod(String name,Class<?>... parameterTypes):
 *                  参数:
 *                      name : 方法名;
 *                      Class ... : 形参的Class类型对象
 *      public Method getDeclaredMethod(String name,Class<?>... parameterTypes)
 *
 *   调用方法:
 *      Method --> public Object invoke(Object obj,Object... args):
 *                  参数说明:
 *                  obj : 要调用方法的对象;
 *                  args:调用方式时所传递的实参;
):
 */

获取成员变量


/*
 * 获取成员变量并调用:
 *
 * 1.批量的
 *      1).Field[] getFields():获取所有的"公有字段"
 *      2).Field[] getDeclaredFields():获取所有字段,包括:私有、受保护、默认、公有;
 * 2.获取单个的:
 *      1).public Field getField(String fieldName):获取某个"公有的"字段;
 *      2).public Field getDeclaredField(String fieldName):获取某个字段(可以是私有的)
 *
 *   设置字段的值:
 *      Field --> public void set(Object obj,Object value):
 *                  参数说明:
 *                  1.obj:要设置的字段所在的对象;
 *                  2.value:要为字段设置的值;
 *
 */

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值