判断实例所属对象
obj instanceof class
也就是说这个对象是不是这种类型,
1.一个对象是本身类的一个对象
2.一个对象是本身类父类(父类的父类)和接口(接口的接口)的一个对象
3.所有对象都是Object
4.凡是null有关的都是false: null instanceof class
class.isInstance(obj)
这个对象能不能被转化为这个类
1.一个对象是本身类的一个对象
2.一个对象能被转化为本身类所继承类(父类的父类等)和实现的接口(接口的父接口)强转
3.所有对象都能被Object的强转
4.凡是null有关的都是false: class.inInstance(null)
类名.class和对象.getClass()几乎没有区别,因为一个类被类加载器加载后,就是唯一的一个类。
一个实例搞定:
class A {}class B extends A {}public class Test {public static void main(String[] args) {B b = new B();A a = new A();A ba = new B();System.out.println("1------------");System.out.println(b instanceof B);System.out.println(b instanceof A);System.out.println(b instanceof Object);System.out.println(null instanceof Object);System.out.println("2------------");System.out.println(b.getClass().isInstance(b));System.out.println(b.getClass().isInstance(a));System.out.println("3------------");System.out.println(a.getClass().isInstance(ba));System.out.println(b.getClass().isInstance(ba));System.out.println(b.getClass().isInstance(null));System.out.println("4------------");System.out.println(A.class.isInstance(a));System.out.println(A.class.isInstance(b));System.out.println(A.class.isInstance(ba));System.out.println("5------------");System.out.println(B.class.isInstance(a));System.out.println(B.class.isInstance(b));System.out.println(B.class.isInstance(ba));System.out.println("6------------");System.out.println(Object.class.isInstance(b));System.out.println(Object.class.isInstance(null));}}
运行结果:

获取私有变量和方法
Despite the common belief it is actually possible to access private fields and methods of other classes via Java Reflection. It is not even that difficult. This can be very handy during unit testing. This text will show you how.
Note: This only works when running the code as a standalone Java application, like you do with unit tests and regular applications. If you try to do this inside a Java Applet, you will need to fiddle around with the SecurityManager. But, since that is not something you need to do very often, it is left out of this text so far.
Note: There has been a lot of talk about disabling the ability to access private fields via reflection from Java 9. From my experiments it seems to still be possible in Java 9, but be aware that this might change in a future Java version.
Accessing Private Fields
To access a private field you will need to call the Class.getDeclaredField(String name) or Class.getDeclaredFields() method. The methods Class.getField(String name) and Class.getFields() methods only return public fields, so they won’t work. Here is a simple example of a class with a private field, and below that the code to access that field via Java Reflection:
// 通过反射获取类定义的变量public void testField() throws Exception {@SuppressWarnings("rawtypes")Class clazz = Class.forName("java.lang.String");Field[] fields = clazz.getFields();for (Field f : fields) {System.out.println(f.getName());}}
example:
public class PrivateObject {private String privateString = null;public PrivateObject(String privateString) {this.privateString = privateString;}}PrivateObject privateObject = new PrivateObject("The Private Value");Field privateStringField = PrivateObject.class.getDeclaredField("privateString");privateStringField.setAccessible(true);String fieldValue = (String) privateStringField.get(privateObject);System.out.println("fieldValue = " + fieldValue);
This code example will print out the text “fieldValue = The Private Value”, which is the value of the private field privateString of the PrivateObject instance created at the beginning of the code sample.
Notice the use of the method PrivateObject.class.getDeclaredField("privateString"). It is this method call that returns the private field. This method only returns fields declared in that particular class, not fields declared in any superclasses.
Notice the line in bold too. By calling Field.setAcessible(true) you turn off the access checks for this particular Field instance, for reflection only. Now you can access it even if it is private, protected or package scope, even if the caller is not part of those scopes. You still can’t access the field using normal code. The compiler won’t allow it.
Modify Private Field
待获取的name如下:
public class Pojo {private StringBuilder name = new StringBuilder("default");public void printName() {System.out.println(name);}}
Pojo p = new Pojo();// 查看被修改之前的值p.printName();// 反射获取字段, name成员变量Field nameField = p.getClass().getDeclaredField("name");// 由于name成员变量是private, 所以需要进行访问权限设定nameField.setAccessible(true);// 使用反射进行赋值nameField.set(p, new StringBuilder("111"));// 打印查看被修改后的值p.printName();
Accessing Fields by Type
关键代码:
- Modifier.isPublic(field.getModifiers()) 判断是否是public
- Modifier.isStatic(field.getModifiers()) 判断是否是static
- field.getGenericType() 获取变量类型
//根据int类型的值映射到对应的变量名public static Map<Integer, String> getAllPublicStaticIntField(Class<?> clazz) {Map<Integer, String> fieldsMap = new HashMap<>();try {//Field[] fields = clazz.getFields();//获取的是共有方法Field[] fields = clazz.getDeclaredFields(); //获取所有方法for (Field field : fields) {int modifiers = field.getModifiers();boolean isPublic = Modifier.isPublic(modifiers);boolean isStatic = Modifier.isStatic(modifiers);boolean isInt = field.getGenericType() == int.class;if (isPublic && isStatic && isInt) {fieldsMap.put((Integer) field.get(null), field.getName());}}} catch (Exception e) {e.printStackTrace();}return fieldsMap;}
Accessing Private Methods
To access a private method you will need to call the Class.getDeclaredMethod(String name, Class[] parameterTypes) or Class.getDeclaredMethods() method. The methods Class.getMethod(String name, Class[] parameterTypes) and Class.getMethods() methods only return public methods, so they won’t work. Here is a simple example of a class with a private method, and below that the code to access that method via Java Reflection:
// 通过反射获取类定义的方法
public void testMethod() throws Exception {
@SuppressWarnings("rawtypes")
Class clazz = Class.forName("java.lang.String");
Method[] m = clazz.getDeclaredMethods();
for (int i = 0; i < m.length; i++) {
System.out.println(m[i].getName() + " " + m[i].getDeclaringClass());
}
}
// 通过反射获取类定义的构造方法
public void testConstructor() throws Exception {
@SuppressWarnings("rawtypes")
Class clazz = Class.forName("java.lang.String");
@SuppressWarnings("rawtypes")
Constructor[] cons = clazz.getConstructors();
for (@SuppressWarnings("rawtypes")
Constructor c : cons) {
System.out.println(c + " " + c.getDeclaringClass());
}
}
example:
public class PrivateObject {
private String privateString = null;
public PrivateObject(String privateString) {
this.privateString = privateString;
}
private String getPrivateString(){
return this.privateString;
}
}
PrivateObject privateObject = new PrivateObject("The Private Value");
Method privateStringMethod = PrivateObject.class.
getDeclaredMethod("getPrivateString", null);
privateStringMethod.setAccessible(true);
String returnValue = (String)
privateStringMethod.invoke(privateObject, null);
System.out.println("returnValue = " + returnValue);
This code example will print out the text “returnValue = The Private Value”, which is the value returned by the method getPrivateString() when invoked on the PrivateObject instance created at the beginning of the code sample.
Notice the use of the method PrivateObject.class.getDeclaredMethod("privateString"). It is this method call that returns the private method. This method only returns methods declared in that particular class, not methods declared in any superclasses.
Notice the line in bold too. By calling Method.setAcessible(true) you turn off the access checks for this particular Method instance, for reflection only. Now you can access it even if it is private, protected or package scope, even if the caller is not part of those scopes. You still can’t access the method using normal code. The compiler won’t allow it.
