Java反射的简单使用

本文详细介绍了如何在Java中通过反射机制,分别使用对象名.getClass(), 类名.class, 和 Class.forName()获取并调用MyTest类的私有属性和方法,探讨了反射与封装的关系,指出虽然反射可以访问私有元素,但并不违背封装原则。
摘要由CSDN通过智能技术生成

Java反射的简单使用

前言:什么是java反射?

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

使用Java反射的三种方式
  1. 对象名 . getClass();
  2. 类名 . class;
  3. Class . forName( " 类的路径 " )(常用)
1. 创建一个MyTest类,封装私有属性,使用反射来操作MyTest类
package cn.kgc.util;
public class MyTest {
    private int id;
    private String name;
    private int age;

	//私有方法
	private void test(int ids){
        System.out.println("ids = " + ids+ids);
    }
    public MyTest() {
    }
    @Override
    public String toString() {
        return "MyTest{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    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 int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}

2. 使用第一种方式 “对象名 . getClass();” ,获取并使用MyTest类的私有方法"test"
    @Test
    public void S3() throws InvocationTargetException, IllegalAccessException {
        //创建MyTest对象
        MyTest myTest = new MyTest();
        //使用对象名.getClass方法
        Class<? extends MyTest> aClass = myTest.getClass();
        //获取MyTest所有方法,返回Method数组
        Method[] declaredMethods = aClass.getDeclaredMethods();
        //遍历Method数组
        for (Method declaredMethod : declaredMethods) {
            //打印MyTest下所有的方法
            System.out.println("declaredMethod = " + declaredMethod.getName());
            //---------------------------------------------------------------------------
            //获取的私有构造进行暴力访问,如果想要访问请打开权限为[true].
            declaredMethod.setAccessible(true);
            //如果得到的方法名与私有方法test相同,调用declaredMethod的invoke方法,向test里面赋值1
            if (declaredMethod.getName() == "test"){
                declaredMethod.invoke(myTest,1);
            }
        }
    }
------------------------------------------------ S3 输出数据 --------------------------------------------------
declaredMethod = toString
declaredMethod = getName
declaredMethod = getId
declaredMethod = setName
declaredMethod = test
ids = 11    //这是test方法的打印结果
declaredMethod = setId
declaredMethod = setAge
declaredMethod = getAge
3. 使用第二种方式 “类名 . class;” ,获取并使用MyTest类的私有方法"test"
    @Test
    public void S1() throws InvocationTargetException, IllegalAccessException {
        Class b = MyTest.class;
        Method[] methods = b.getDeclaredMethods();
        for (Method method : methods) {
            method.setAccessible(true);
            if (method.getName()=="test"){
                MyTest myTest = new MyTest();
                method.invoke(myTest,1);
            }
        }
    }
4. 使用第三种方式 “Class . forName(String pathName )” ,获取并使用MyTest类的私有方法"test"
    @Test
    public void S4() throws ClassNotFoundException, InvocationTargetException, IllegalAccessException {
        Class<?> aClass = Class.forName("cn.kgc.util.MyTest");
        Method[] declaredMethods = aClass.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            declaredMethod.setAccessible(true);
            if (declaredMethod.getName() == "test"){
                MyTest myTest = new MyTest();
                declaredMethod.invoke(myTest,3);
            }
        }
    }
最后:Java封装和Java反射是不是冲突呢,Java反射会不会破坏Java封装的封装性?

​······ 首先,封装是将具体的实现细节隐藏,而把功能作为整体提供给类的外部使用,也就是说,公有方法能够完成类所具有的功能。当别人使用这个类时,如果通过反射直接调用私有方法,可能根本实现不了类的功能,甚至可能会出错,因此通过反射调用私有方法可以说是没有任何用处的,开发人员没有必要故意去破坏封装好的类。从这点上看,封装性并没有被破坏。(摘自百度问答)
······个人的见解:反射确实可以得到一切 类中的东西(包括私有的属性、方法等),但是或许不算是破坏封装,私有方法是为了让继承的类无法使用,避免调用那些被设为私有的方法出现一些不必要的错误。这就是封装性。反射虽然可以获取私有方法并使用方法,只能说是其功能强大,可以在保证在调用私有方法不会出现错误,但是并没有反射调用方法后,该方法就不是私有的了。他仍然是私有的,仍然在子类中不可见。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值