16-2.Java 反射之 setAccessible 方法详解(Java 访问检查、反射的访问检查、setAccessible())

一、Java 访问检查

1、基本介绍
  • 访问检查就是查看成员使用是否符合访问权限(public、protected、default、private)
2、演示
  • Person.java
package com.my.entity;

public class People {
    private int privateVar = 1;
    int defaultVar = 2;
    protected int protectedVar = 3;
    public int publicVar = 4;
}
  • PeopleTest.java
package com.my.test;

import com.my.entity.People;

public class PeopleAccessibleTest {
    public static void main(String[] args) {
        People p = new People();
        System.out.println(p.privateVar);
        System.out.println(p.defaultVar);
        System.out.println(p.protectedVar);
        System.out.println(p.publicVar);
    }
}
  • 只有 publicVar 的使用符合访问权限

二、反射的访问检查

1、基本介绍
  • 一个类的成员属性、成员方法和构造函数,在反射中分别被抽象为 Field、Method 和 Counstructor 类

  • 可以使用 Field、Method 和 Counstructor 对象访问类的成员,成员的访问权限,编译器是不知道的,只有运行时才知道,因此对于类成员访问权限的检查只能交给虚拟机

2、演示
  • ReflectionAccessibleTest.java
package com.my.test;

import com.my.entity.People;

import java.lang.reflect.Field;

public class ReflectionAccessibleTest {
    public static void main(String[] args) throws IllegalAccessException {
        People people = new People();
        Class<People> peopleClass = People.class;
        Field[] declaredFields = peopleClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField.get(people));
        }
    }
}
  • 抛出异常:java.lang.IllegalAccessException
3、小结
  • 访问检查可以在编译器编译时进行或者虚拟机运行时进行

三、setAccessible()

1、基本介绍
  • void setAccessible(boolean flag) 方法是 AccessibleObject 类中的一个方法,它是Field、 Method、Constructor的公共父类

  • 当 Field、Method 和 Constructor 分别进行设置属性值、获取属性值、调用方法或创建和初始化类的新实例时,将执行运行时访问检查

  • void setAccessible(boolean flag) 方法为反射对象设置可访问标志,flag 为 true 表示表示屏蔽 Java 语言的(运行时)访问检查

  • boolean isAccessible() 方法会返回对象的可访问标志

2、演示
  • SetAccessibleTest.java
package com.my.test;

import com.my.entity.People;

import java.lang.reflect.Field;

public class SetAccessibleTest {
    public static void main(String[] args) throws IllegalAccessException {
        People people = new People();
        Class<People> peopleClass = People.class;
        Field[] declaredFields = peopleClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            declaredField.setAccessible(true);
            System.out.println(declaredField.get(people));
        }
    }
}
3、注意事项
(1)说明
  • 方法名 setAccessible 很容易让人产生误解,给人的感觉是设置了成员的可访问性,例如,认为 public 修饰的成员是任意类都可以访问的,所以可访问标志是 true;觉得 private 修饰的成员只有本类可以访问,所以可访问标志是false,其实不然,不管是什么访问权限,其可访问标志的值都为 false
(2)演示
  • IsAccessibleTest 类
package com.my.test;

import com.my.entity.People;

import java.lang.reflect.Field;

public class IsAccessibleTest {
    public static void main(String[] args) {
        Class<People> peopleClass = People.class;
        Field[] declaredFields = peopleClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField.isAccessible());
        }
    }
}
(3)小结
  • 可访问标志表示是否屏蔽 Java 语言的访问检查,默认值是false

  • 可以通过 setAccessible(true) 修改默认值,如此会屏蔽 Java 语言的(运行时)访问检查,使得对象的私有成员可以访问,而不报错

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值