一、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 语言的(运行时)访问检查,使得对象的私有成员可以访问,而不报错