三种方式获取Class对象java
public class SubPerson extends Person { public Long subId; private String subName; private SubPerson() { } public SubPerson(Long subId, String subName) { this.subId = subId; this.subName = subName; } } public class Person { public Long id; private String name; public Person() { } class Card{ private String id; public Card() { } public String getId() { return id; } public void setId(String id) { this.id = id; } } } //1 Class personClass1 = new Person().getClass(); System.out.println(personClass1); //2 Class personClass2 = Person.class; System.out.println(personClass2); //3 try { Class personClass3 = Class.forName("com.banary.reflect.Person"); System.out.println(personClass3); }catch (ClassNotFoundException e){ e.printStackTrace(); }
public static void ClassMethodTest(){ //获取全类名 System.out.println(Person.class.getName()); System.out.println(int.class.getName()); System.out.println(int[][][].class.getName()); System.out.println(Person.Card.class.getName()); System.out.println(new Runnable() { @Override public void run() { } }.getClass().getName()); Runnable runnable = ()-> System.out.println("test"); System.out.println(runnable.getClass().getName()); System.out.println("------------分割线------------"); //获取类名 System.out.println(Person.class.getSimpleName()); System.out.println(int.class.getSimpleName()); System.out.println(int[][][].class.getSimpleName()); System.out.println(Person.Card.class.getSimpleName()); System.out.println(new Runnable() { @Override public void run() { } }.getClass().getSimpleName()); System.out.println(runnable.getClass().getSimpleName()); System.out.println("------------分割线------------"); /** * 获取官方类名 * 1. getCanonicalName() 返回的也是全限定类名,可是对于内部类,不用 $ 开头,而用 .。 * 2. getCanonicalName() 对于数组类型的 Class,同 simplename 同样直接在后面添加 [] 。 * 3. getCanonicalName() 不一样于 simplename 的地方是,不存在 canonicalName 的时候返回 null 而不是空字符串。 * 4. 局部类和匿名内部类不存在 canonicalName。 */ System.out.println(Person.class.getCanonicalName()); System.out.println(int.class.getCanonicalName()); System.out.println(int[][][].class.getCanonicalName()); System.out.println(Person.Card.class.getCanonicalName()); System.out.println(new Runnable() { @Override public void run() { } }.getClass().getCanonicalName()); System.out.println(runnable.getClass().getCanonicalName()); }
// 十进制 System.out.println(Modifier.class.getModifiers()); // 十六进制 System.out.println(Integer.toHexString(Modifier.class.getModifiers())); // 对应的真实修饰符 System.out.println(java.lang.reflect.Modifier.toString(Modifier.class.getModifiers()));
经过上述的方法,可见java中是采用二进制位来表示修饰符,下列为java中修饰符实现数组
public class Modifier { // 2^0 public static final int PUBLIC = 0x00000001; // 2^1 public static final int PRIVATE = 0x00000002; // 2^2 public static final int PROTECTED = 0x00000004; public static final int STATIC = 0x00000008; public static final int FINAL = 0x00000010; public static final int SYNCHRONIZED = 0x00000020; public static final int VOLATILE = 0x00000040; public static final int TRANSIENT = 0x00000080; public static final int NATIVE = 0x00000100; public static final int INTERFACE = 0x00000200; public static final int ABSTRACT = 0x00000400; public static final int STRICT = 0x00000800; public static String toString(int mod) { StringBuilder sb = new StringBuilder(); int len; if ((mod & PUBLIC) != 0) sb.append("public "); if ((mod & PROTECTED) != 0) sb.append("protected "); if ((mod & PRIVATE) != 0) sb.append("private "); /* Canonical order */ if ((mod & ABSTRACT) != 0) sb.append("abstract "); if ((mod & STATIC) != 0) sb.append("static "); if ((mod & FINAL) != 0) sb.append("final "); if ((mod & TRANSIENT) != 0) sb.append("transient "); if ((mod & VOLATILE) != 0) sb.append("volatile "); if ((mod & SYNCHRONIZED) != 0) sb.append("synchronized "); if ((mod & NATIVE) != 0) sb.append("native "); if ((mod & STRICT) != 0) sb.append("strictfp "); if ((mod & INTERFACE) != 0) sb.append("interface "); if ((len = sb.length()) > 0) /* trim trailing space */ return sb.toString().substring(0, len-1); return ""; } }
类的属性包括Field、Method、Constructorapp
Class personClass = SubPerson.class; //获取自身的全部的 public 属性,包括从父类继承下来的, 可能会抛出运行时异常SecurityException Field[] fields = personClass.getFields(); for (Field field : fields) { System.out.println(field.getName()); } //根据field名获取, 可能会抛出NoSuchFieldException(检查型), SecurityException try { Field field1 = personClass.getField("subId"); System.out.println(field1.getName()); } catch (NoSuchFieldException e){ e.printStackTrace(); } System.out.println("------------分割线------------"); //获取全部的属性,但不包括从父类继承下来的属性 Field[] declaredFields = personClass.getDeclaredFields(); for (Field declaredField : declaredFields) { System.out.println(declaredField.getName()); } System.out.println("------------分割线------------"); try{ Field field2 = personClass.getDeclaredField("subName"); System.out.println(field2.getName()); } catch (NoSuchFieldException e){ e.printStackTrace(); }
# 可以获取到泛型类型 public Type getGenericType() {} public Class<?> getType() {}
# 同class和Method的修饰符同样 public int getModifiers() {}
#设置值 public Object get(Object obj); public int getInt(Object obj); public long getLong(Object obj) throws IllegalArgumentException, IllegalAccessException; public float getFloat(Object obj) throws IllegalArgumentException, IllegalAccessException; public short getShort(Object obj) throws IllegalArgumentException, IllegalAccessException; public double getDouble(Object obj) throws IllegalArgumentException, IllegalAccessException; public char getChar(Object obj) throws IllegalArgumentException, IllegalAccessException; public byte getByte(Object obj) throws IllegalArgumentException, IllegalAccessException; public boolean getBoolean(Object obj) throws IllegalArgumentException, IllegalAccessException public void set(Object obj, Object value); # 获取值 public void getInt(Object obj,int value); public void getLong(Object obj,long value) throws IllegalArgumentException, IllegalAccessException; public void getFloat(Object obj,float value) throws IllegalArgumentException, IllegalAccessException; public void getShort(Object obj,short value) throws IllegalArgumentException, IllegalAccessException; public void getDouble(Object obj,double value) throws IllegalArgumentException, IllegalAccessException; public void getChar(Object obj,char value) throws IllegalArgumentException, IllegalAccessException; public void getByte(Object obj,byte b) throws IllegalArgumentException, IllegalAccessException; public void getBoolean(Object obj,boolean b) throws IllegalArgumentException, IllegalAccessException
Class 自己不对成员进行储存,它只提供检索,因此须要用 Field、Method、Constructor 对象来承载这些成员,因此,针对成员的操做时,通常须要为成员指定类的实例引用。ide
getName()
#获取全部的参数 public Parameter[] getParameters() {} // 获取全部的参数类型 public Class<?>[] getParameterTypes() {} // 获取全部的参数类型,包括泛型 public Type[] getGenericParameterTypes() {}
// 获取返回值类型 public Class<?> getReturnType() {} // 获取返回值类型包括泛型 public Type getGenericReturnType() {}
public int getModifiers() {}
public Class<?>[] getExceptionTypes() {} # 包括泛型 public Type[] getGenericExceptionTypes() {}
#invoke() 方法中第一个参数 Object 实质上是 Method 所依附的 Class 对应的类的实例,若是这个方法是一个静态方法,那么 ojb 为 null,后面的可变参数 Object 对应的天然就是参数 #invoke() 返回的对象是 Object,因此实际上执行的时候要进行强制转换。 #在对 Method 调用 invoke() 的时候,若是方法自己会抛出异常,那么这个异常就会通过包装,由 Method 统一抛出 InvocationTargetException。而经过 InvocationTargetException.getCause() 能够获取真正的异常。 public Object invoke(Object obj, Object... args) {}
public static void getConstructor(){ Class subPersonClass = SubPerson.class; //获取全部的public构造器,因为父类的构造器不能继承,因此获取不到 Constructor[] constructors = subPersonClass.getConstructors(); for (Constructor c : constructors) { System.out.println(c.toString()); } System.out.println("------------分割线------------"); //获取全部的构造器,包括私有和公开的 Constructor[] declaredConstructors = subPersonClass.getDeclaredConstructors(); for (Constructor declaredConstructor :declaredConstructors) { System.out.println(declaredConstructor.toString()); } }
# Class.newInstance() 只能调用无参的构造方法,而 Constructor.newInstance() 则能够调用任意的构造方法。 # Class.newInstance() 经过构造方法直接抛出异常,而 Constructor.newInstance() 会把抛出来的异常包装到 InvocationTargetException 里面去,这个和 Method 行为一致。 # Class.newInstance() 要求构造方法可以被访问,而 Constructor.newInstance() 却可以访问 private 修饰的构造器。
getName(); #获取数组的里面的元素的类型,好比 int[] 数组的 componentType 天然就是 int getComponentType();
public static Object newInstance(Class<?> componentType, int... dimensions) throws IllegalArgumentException, NegativeArraySizeException {}
e.g.ui
# 建立一个 int[2][3] 的数组 Array.newInstance(int.class,2,3);
public void set(Object obj, Object value) throws IllegalArgumentException, IllegalAccessException; public Object get(Object obj) throws IllegalArgumentException, IllegalAccessException; public static void set(Object array, int index, Object value) throws IllegalArgumentException, ArrayIndexOutOfBoundsException; public static void setBoolean(Object array, int index, boolean z) throws IllegalArgumentException, ArrayIndexOutOfBoundsException; public static Object get(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException; public static short getShort(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
// 用来断定 Class 对象是否是枚举类型 Class.isEnum() // 获取全部的枚举常量 Class.getEnumConstants() // 判断一个 Field 是否是枚举常量 Field.isEnumConstant()
public static void reflectEnum() throws Exception{ Class colorClass = Color.class; if(colorClass.isEnum()){ System.out.println(String.format("class Color %s is Enum", colorClass.getName())); Field[] fields = colorClass.getDeclaredFields(); for (Field field:fields) { if(field.isEnumConstant()){ System.out.println(String.format("%s is EnumConstant", field.getName())); }else{ System.out.println(String.format("%s is not EnumConstant", field.getName())); } } } System.out.println("_____________________"); Constructor[] constructors = colorClass.getDeclaredConstructors(); for(Constructor constructor : constructors){ System.out.println(constructor.getName()); constructor.setAccessible(true); Color color = (Color) constructor.newInstance("123123"); System.out.println(color.getKey()); } Color color = (Color) colorClass.newInstance(); System.out.println(color.getKey()); }