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(ClassannotationClass); // 3.字段类型 Type getGenericType(); Class getType(); // 4.字段修饰符 int modifer=field.getModifiers(); String modify = Modifier.toString(modifiers); // 5.字段名称 String getName(); }
参考博客: