Java Reflection 反射机制2 获取运行时类的对象的属性 Class类的方法
方法名
介绍
参数
getName()
获得类的全名,包括包。如:com.uwupu.User
getSimpleName()
获得类的名字。如:User
getFields()
获取类的public属性。
getDeclaredFields()
获得类的所有属性。
getDeclaredField(param)
通过名字获得类的属性
属性的名字
getDeclaredConstructors()
获得类的所有的构造器
getConstructors()
获得类的public的构造器
getConstructor(param)
通过构造器的参数获得类的构造器
构造器的参数
代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 public class Test { public static void main (String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException { Class c1 = Class.forName("Demo2_Reflection.User" ); System.out.println(c1.getName()); System.out.println(c1.getSimpleName()); System.out.println("------------------" ); Field[] fields = c1.getFields(); for (Field f : fields){ System.out.println(f); } System.out.println("------------------" ); fields = c1.getDeclaredFields(); for (Field f : fields){ System.out.println(f); } Field name = c1.getDeclaredField("name" ); System.out.println(name); Method[] methods = c1.getMethods(); for (Method method : methods) { System.out.println("getMethods:" +method); } methods = c1.getDeclaredMethods(); for (Method method : methods) { System.out.println("getDeclaredMethods:" +method); } Method getMethod = c1.getMethod("getName" ); Method setMethod = c1.getMethod("setName" ,String.class); System.out.println(getMethod); System.out.println(setMethod); Constructor[] constructors = c1.getDeclaredConstructors(); for (Constructor constructor : constructors) { System.out.println(constructor); } constructors = c1.getConstructors(); for (Constructor constructor : constructors) { System.out.println(constructor); } Constructor constructor = c1.getConstructor(String.class,int .class,int .class); System.out.println(constructor); } }
对Class对象进行一些操作 创建类的对象: 方法1: 调用Class对象的newInstance()方法。
类必须有一个无参构造器;
需要足够的类的构造器访问权限。
代码:
1 2 3 4 5 6 7 8 9 10 public class Demo8_ 通过Class对象对类进行一些操作 { public static void main (String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException { Class c1 = Class.forName("Demo2_Reflection.User" ); User user = (User)c1.newInstance(); System.out.println(user); } }
方法2: 1 2 3 4 5 6 7 8 9 10 11 public class Demo8_ 通过Class对象对类进行一些操作 { public static void main (String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { Class c1 = Class.forName("Demo2_Reflection.User" ); Constructor constructor = c1.getDeclaredConstructor(String.class,int .class,int .class); User user2 = (User) constructor.newInstance("张三" ,1 ,22 ); System.out.println(user2); } }
通过反射操作方法 Invoke
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public class Demo8_ 通过Class对象对类进行一些操作 { public static void main (String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { Class c1 = Class.forName("Demo2_Reflection.User" ); Constructor constructor = c1.getDeclaredConstructor(String.class,int .class,int .class); User user2 = (User) constructor.newInstance("张三" ,1 ,22 ); System.out.println(user2); Method setName = c1.getDeclaredMethod("setName" ,String.class); setName.invoke(user2,"李四" ); System.out.println(user2); } }
1 2 User{name='张三', id=1, age=22} User{name='李四', id=1, age=22}
通过反射操作属性 代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public class Demo8_ 通过Class对象对类进行一些操作 { public static void main (String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException { Class c1 = Class.forName("Demo2_Reflection.User" ); Constructor constructor = c1.getDeclaredConstructor(String.class,int .class,int .class); User user2 = (User) constructor.newInstance("张三" ,1 ,22 ); System.out.println(user2); Field name = c1.getDeclaredField("name" ); name.setAccessible(true ); name.set(user2,"王五" ); System.out.println(user2); } }
1 2 User{name='李四', id=1, age=22} User{name='王五', id=1, age=22}
注意
若要”使用Field的set方法操作属性“或“使用invoke方法操作原方法”,若属性或方法用private修饰,则不能直接操作,需要用setAccessible(true)
方法关掉权限监测,才可直接操作。
setAccessible
Method、Field和Constructor对象都有setAccessible()方法;
**setAccessible
**作用是启动和禁用访问安全检查的开关。
参数为true表示关闭反射对象 的访问检查 。默认为false。
可以提高反射效率。若代码中必须使用反射,且该句代码需要频繁地被调用,请一定设置为true。
获取泛型信息 Java采用泛型擦除的机制来引入泛型,Java中的泛型仅仅是给编译器javac使用的,确保数据的安全性和免去强制类型转换问题。一旦编译完成,所有和泛型有关的类型全部擦除。
为了通过反射操作这些类型,Java新增了集中类型来代表不能归一到Class类中的类型但是又和原始类型齐名的类型。
类型名
描述
ParameterizedType
表示一种参数化类型,如Collection<String>
GenericArrayType
表示一种元素类型是参数化类型或者类型变量的数组类型。
TypeVariable
是各种类型变量的公共父接口。
WildcardType
代表一种通配符类型表达式。
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 public class Test9 { public void test01 (Map<String, User> map, List<User> list) { System.out.println("test01" ); } public Map<String,User> test02 () { System.out.println("test02" ); return null ; } public static void main (String[] args) throws NoSuchMethodException { Method method = Test9.class.getMethod("test01" ,Map.class,List.class); Type[] types = method.getGenericParameterTypes(); for (Type type : types){ System.out.println("# " +type); if (type instanceof ParameterizedType){ Type[] type2 =((ParameterizedType) type).getActualTypeArguments(); for (Type type3 :type2){ System.out.println(type3); } } } System.out.println("--------------------------------" ); method = Test9.class.getMethod("test02" ); Type returnType = method.getGenericReturnType(); System.out.println("# " +returnType); if (returnType instanceof ParameterizedType){ Type[] type2 =((ParameterizedType) returnType).getActualTypeArguments(); for (Type type3 :type2){ System.out.println(type3); } } } }
获取注解信息 ORM
Object relationship Mapping -> 对象关系映射
代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 public class Demo10_ 通过反射获得注解 { public static void main (String[] args) throws Exception { Class c1 = Class.forName("MyClass" ); MyAnnotation classAnnotation = (MyAnnotation) c1.getAnnotation(MyAnnotation.class); System.out.println(classAnnotation); System.out.println( "id: " + classAnnotation.id() + " name: " +classAnnotation.name() ); Field field = c1.getField("id" ); MyAnnotation myAnnoation = field.getAnnotation(MyAnnotation.class); System.out.println(myAnnoation); System.out.println( "id: " + myAnnoation.id() + " name: " +myAnnoation.name() ); Method method = c1.getMethod("int2String" , int .class); MyAnnotation methodAnnoation = method.getAnnotation(MyAnnotation.class); System.out.println(methodAnnoation); System.out.println( "id: " + methodAnnoation.id() + " name: " +methodAnnoation.name() ); } } @MyAnnotation(name = "MyClass",id = 1) class MyClass { @MyAnnotation(name = "id",id = 2) public int id; @MyAnnotation(name = "int2String",id = 3) public String int2String (int value) { return String.valueOf(value); } } @Target({ElementType.FIELD,ElementType.TYPE,ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @interface MyAnnotation{ String name () ; int id () ; }
1 2 3 4 5 6 @MyAnnoation(name=MyClass, id=1) id: 1 name: MyClass @MyAnnoation(name=id, id=2) id: 2 name: id @MyAnnoation(name=int2String, id=3) id: 3 name: int2String