Java高级特性——反射

一、简介

定义:

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

面试经常问:如何在一个类中访问另一个类的私有方法或属性?

答:1.通过几种方式获得类对象,然后通过getDeclaredField()获取Field对象,再设置字段对象的setAccessible(true),最后设置通过get/set来获取、设置字段值。

2.通过几种方式获得类对象,然后通过getDeclaredMethod()获取Method对象,在设置(方法对象的setAccessible(true),最后用调用invoke()方法调用该方法(需要传参指定类对象实例和方法参数Obj[]数组)

需要了解这4个对象:

类名用途

Class类  代表类的实体,在运行的Java应用程序中表示类和接口

Field类   代表类的成员变量(成员变量也称为类的属性)

Method类  代表类的方法

Constructor类  代表类的构造方法

二、实例

话不多少,撸代码了

1.定义一个含有私有方法和属性的类

package com.naland.yc.demo.test.reflect;

public class ReflecTest {

    private String name;

    private int age;

    private void getPerson(String name,int age){
        System.out.println("姓名:"+name+ " 年龄:"+age);
    }

    public void pubGetPerson(){
        System.out.println("公有方法访问   "+"姓名:"+name+ " 年龄:"+age);
    }

    private ReflecTest(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public ReflecTest(){

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

2.反射调用实例

package com.naland.yc.demo.test.reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflectTest2 {
    public static void main(String[] args) {
        //new一个对象
        ReflecTest test = new ReflecTest();
        /**
         * 获取Class对象
         */
        //方式1   实例.getClass()
        Class test1 = test.getClass();

        //方式2   Class.forName("com.naland.yc.demo.test.reflect.ReflectTest")
        Class test2 = null;
        try {
            test2 = Class.forName("com.naland.yc.demo.test.reflect.ReflecTest");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        //方式3   类名.class
        Class test3 = ReflecTest.class;

        //类对象获取实例
        try {
            ReflecTest test1Instance = (ReflecTest) test1.newInstance();
            ReflecTest test2Instance = (ReflecTest) test2.newInstance();
            ReflecTest test3Instance = (ReflecTest) test3.newInstance();

            test1Instance.pubGetPerson();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }


        //访问私有属性
        Field field = null;
        try {
            field = test1.getDeclaredField("name");
            field.setAccessible(true);
            //此处需要传入实例对象
            System.out.println(field.get(test));
            field.set(test, "naland");
            test.pubGetPerson();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        //访问私有方法
        Method method = null;
        try {
            //需要传入方法名和参数类型的class
            method = test2.getDeclaredMethod("getPerson",new Class[]{String.class,int.class});
            method.setAccessible(true);
            method.invoke(test, new Object[]{"张三", 25});
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

        //访问私有构造方法
        Constructor constructor=null;
        try {
            constructor=test3.getDeclaredConstructor(new Class[]{String.class,int.class});
            constructor.setAccessible(true);
            Object testInstance=constructor.newInstance(new Object[]{"Kobe Brant",38});
            ReflecTest newInstance= (ReflecTest) testInstance;
            System.out.println(newInstance.toString());
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }


    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值