java中private只能被本类访问。但是还可以利用java中的反射从外界调用private变量或方法。
package reflect;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class PrivateCarReflect {
public static void main(String[] args) throws Throwable{
//获取当前线程再获取类加载器
ClassLoader loader = Thread.currentThread().getContextClassLoader();
//通过类加载器获取我们想操作的类
Class clazz = loader.loadClass("reflect.PrivateCar");
//类转换一下
PrivateCar pcar = (PrivateCar) clazz.newInstance();
//field场地,declared宣告,
//field用于获取字段
Field colorFld = clazz.getDeclaredField("color");
//取消java语言访问检查以访问private变量
colorFld.setAccessible(true);
colorFld.set(pcar, "红色");
Method driveMtd = clazz.getDeclaredMethod("drive");
//取消java语言访问检查以访问protected方法
driveMtd.setAccessible(true);
driveMtd.invoke(pcar, (Object[])null);
}
}
反射Class类、Constructor类、Field类。
表示java类的Class类显然要提供一系列的方法,来获得其中的
变量,方法,构造方法,修饰符,包等信息,这些信息就是用相应类的实例对象来表示,它们是Field、Method、Contructor、Package等等。
field中有修饰符、类型、变量名等复杂的描述内容,因此也
可以将字段封装称为一个对象。用来获取类中field的内容,这个对象的描述叫Field。同理方法和构造函数也被封装成对象Method、Constructor。要想对一个类进行内容的获取,必须要先获取该字节码文件的对象。该对象是Class类型。
以下为AccessibleObject、Method、Field类源码:
//AccessibleObject 类是 Field、Method 和 Constructor 对象的基类。
public class AccessibleObject implements AnnotatedElement {
/*
* 1、实现了AnnotatedElement对注解支持的相关方法
* 2、提供访问控制
/
void setAccessible(boolean flag)
设置该对象(Field,Constructor,Method)是否可访问
boolean isAccessible()
该对象是否可访问
void setAccessible(AccessibleObject[] array, boolean flag)
设置这一组对象(Field,Constructor,Method)是否可访问
}
public interface Member{
public static final int PUBLIC = 0; //标识类或接口的所有已声明成员的集合。
public static final int DECLARED = 1; //标识类或接口的所有公共成员(包括继承成员)的集合。
public Class<?> getDeclaringClass();// 所在类
public String getName(); //返回此 Member 表示的底层成员或构造方法的简单名称。
public int getModifiers(); //作为整数返回由此 Member 所表示的成员或构造方法的 Java 语言修饰符。
public boolean isSynthetic(); //如果此成员是编译器引入的,则返回 true;否则,返回 false。
}
public final class Field extends AccessibleObject implements Member{
// 1.字段的设值和取值 ,对于静态属性,obj传null
set(Object obj, Object value)
setXX(Object obj, Object value) ,比如setInt,setBoolean
Object get(Object obj)
getXX(Object obj) ,比如getInt,getBoolean
// 2.字段上注解的获取
getDeclaredAnnotations()
getAnnotation(Class<T> annotationClass);
// 3.字段类型
Type getGenericType();
Class<?> getType();
// 4.字段修饰符
int modifer=field.getModifiers();
String modify = Modifier.toString(modifiers);
// 5.字段名称
String getName();
}
参考博客: