JavaSE---反射(未完待续)
Posted anpeiyong
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaSE---反射(未完待续)相关的知识,希望对你有一定的参考价值。
java.lang.reflect包下接口及类
Class、Method、Field、Constructor、Array...
Java程序 可以使用 这些 类 动态 获取 某个对象、某个类 运行时信息;
动态 创建 Java对象、动态 调用Java方法、 动态 访问并修改指定对象的属性值;
Type:
Class所实现的接口;
ParameterizedType:
代表一个带泛型参数的类型;
Proxy 与 InvocationHandler:
使用 Proxy 与 InvocationHandler 创建JDK动态代理;
类的唯一标识
同一个JVM进程中: 全限定类名 (包名 + 类名)+ 类加载器 ;
Java程序中 许多对象 运行时 有2种类型:编译时类型、运行时类型,需要 在 运行时 发现 对象的真实信息,有2种做法:
1、编译、运行时 完全知道类型的具体信息
instaceof 类型判断--->类型强转--->使用
2、编译时无法预知类型
只能依赖运行时信息发现 真实信息,使用反射;
1.2 获得Class对象
每个类被加载后,在内存中都会创建一个该类的Class对象,通过Class对象就可以访问JVM中的这个类;
1.1.1 调用Class对象的forName(),返回该类的Class对象 public static Class<?> forName(String className)
className:类的全限定名
1.1.2 调用某个类的class属性,将返回该类的Class对象;
1.1.3 调用某个类的getClass(),将返回该类的Class对象;
1.3 从Class对象中获取信息
1.1.1 访问Class对应类包含的构造器
1.1.2 访问Class对应类包含的方法
1.1.3 访问Class对应类包含的属性
1.1.4 访问Class对应类上的注解
1.1.5 访问Class对应类包含的内部类
1.1.6 访问Class对应类包含的外部类
1.1.7 访问Class对应类所继承的父类、实现的接口
1.1.8 判断Class对应类是接口、注解、枚举等
1.4 使用反射生成并操作对象
package com.an.reflect; /** * @author apy * @description * @date 2021/5/6 14:28 */ public class A { private String name; private String job; public A(){ } public A(String name){ this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } private void setJob(String job){ this.job = job; } public String getJob(){ return job; } } package com.an.reflect; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * @author apy * @description * @date 2021/5/6 11:04 */ public class Test { public static void main(String[] args) { testReflect(); } /** * 1、获取Class对象 * 2、对象创建 * 3、调用方法 * 4、访问属性值 */ public static void testReflect(){ try { // 1、根据全限定名 找到JVM中对应的Class对象 Class aClass = Class.forName("com.an.reflect.A"); // 2.1、调用无参构造 Object instance = aClass.newInstance(); // 2.2、调用String参数构造 Constructor stringConstructor = aClass.getConstructor(String.class); Object instance1 = stringConstructor.newInstance("jack"); // 3.1、调用public方法 Method[] methods = aClass.getMethods(); for (Method m:methods) { System.out.println("methods:"+m); } /** * 结果: * methods:public java.lang.String com.an.reflect.A.getJob() * methods:public java.lang.String com.an.reflect.A.getName() * methods:public void com.an.reflect.A.setName(java.lang.String) * methods:public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException * methods:public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException * methods:public final void java.lang.Object.wait() throws java.lang.InterruptedException * methods:public boolean java.lang.Object.equals(java.lang.Object) * methods:public java.lang.String java.lang.Object.toString() * methods:public native int java.lang.Object.hashCode() * methods:public final native java.lang.Class java.lang.Object.getClass() * methods:public final native void java.lang.Object.notify() * methods:public final native void java.lang.Object.notifyAll() */ Method[] declaredMethods = aClass.getDeclaredMethods(); for (Method m:declaredMethods) { System.out.println("declaredMethods:"+m); } /** * 结果: * declaredMethods:public java.lang.String com.an.reflect.A.getJob() * declaredMethods:private void com.an.reflect.A.setJob(java.lang.String) * declaredMethods:public java.lang.String com.an.reflect.A.getName() * declaredMethods:public void com.an.reflect.A.setName(java.lang.String) */ Method publicSetNameMethod = aClass.getMethod("setName", String.class); publicSetNameMethod.invoke(instance, "rose"); //3.2、调用private方法 // 使用 Method的invoke方法 要求有该方法的权限; // 若想调用某个对象的private方法,可以先调用 Method的setAccessible方法 // 值为true时,在使用时将取消 Java语言访问权限检查 // 值为false时,在使用时将实施 Java语言访问权限检查 Method privateSetJobMethod = aClass.getDeclaredMethod("setJob", String.class); privateSetJobMethod.setAccessible(true); privateSetJobMethod.invoke(instance, "teacher"); Field privateJobField = aClass.getDeclaredField("job"); privateJobField.setAccessible(true); System.out.println("instance.job:"+privateJobField.get(instance)); // 4、访问属性值 Field[] fields = aClass.getFields(); for (Field f:fields) { System.out.println("getFields:"+f.getName()); } /** * 结果:无 */ Field[] declaredFields = aClass.getDeclaredFields(); for (Field f:declaredFields) { System.out.println("getDeclaredFields:"+f.getName()); } /** * 结果: * getDeclaredFields:name * getDeclaredFields:job */ // 4.1、访问private属性 // 若想调用某个对象的private属性,可以先调用 Method的setAccessible方法 // 值为true时,在使用时将取消 Java语言访问权限检查 // 值为false时,在使用时将实施 Java语言访问权限检查 Field privateNameField = aClass.getDeclaredField("name"); privateNameField.setAccessible(true); System.out.println("Field.set pre:"+privateNameField.get(instance)); privateNameField.set(instance, "rose1"); Object o = privateNameField.get(instance); System.out.println("Field.get:"+o); /** * 结果: * Field.set pre:rose * Field.get:rose1 */ }catch (ClassNotFoundException e){ e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); }catch (NoSuchFieldException e) { e.printStackTrace(); } } }
JDK动态代理
package com.an.reflect; /** * @author apy * @description * @date 2021/5/6 15:50 */ public interface B { void say(String name); } package com.an.reflect; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; /** * @author apy * @description * @date 2021/5/6 15:52 */ public class BProxy implements InvocationHandler { /** * @param proxy 代理对象 * @param method 正在执行的方法 * @param args 正在执行方法的参数 * @return * @throws Throwable * * 结果: * 代理对象:class com.sun.proxy.$Proxy0 * 正在执行的方法:say * 正在执行的方法参数: * hello, */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("代理对象:"+proxy.getClass()); System.out.println("正在执行的方法:"+method.getName()); System.out.println("正在执行的方法参数:"); for (Object o:args) { System.out.println(o+","); } return null; } } package com.an.reflect; import java.lang.reflect.*; /** * @author apy * @description * @date 2021/5/6 11:04 */ public class Test { public static void main(String[] args) { testDynamicProxy(); } /** * JDK动态代理: * 为 一个或多个接口 创建代理类 | 代理对象 * 提供Proxy、InvocationHandler */ private static void testDynamicProxy() { Object proxyInstance = Proxy.newProxyInstance(B.class.getClassLoader(), new Class[]{B.class}, new BProxy()); B b = (B) proxyInstance; b.say("hello"); } }
反射与泛型
package com.an.reflect; import java.util.Map; /** * @author apy * @description * @date 2021/5/6 14:28 */ public class A { private String name; private String job; private Map<String,Integer> map; public A(){ } public A(String name){ this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } private void setJob(String job){ this.job = job; } public String getJob(){ return job; } } package com.an.reflect; import java.lang.reflect.*; /** * @author apy * @description * @date 2021/5/6 11:04 */ public class Test { public static void main(String[] args) { testGenericProxy(); } /** * 反射与泛型 */ private static void testGenericProxy() { try { Class aClass = Class.forName("com.an.reflect.A"); Field privateJobField = aClass.getDeclaredField("job"); Class<?> privateJobFieldType = privateJobField.getType(); System.out.println("job type:"+privateJobFieldType); Field privateMapField = aClass.getDeclaredField("map"); Type genericType = privateMapField.getGenericType(); ParameterizedType parameterizedType = (ParameterizedType) genericType; Type rawType = parameterizedType.getRawType();// 返回被泛型限制的类型 System.out.println("map rawType:"+rawType); Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();// 返回泛型参数类型 System.out.println("map actualTypeArguments:"); for (Type t:actualTypeArguments) { System.out.println(t+","); } } catch (ClassNotFoundException | NoSuchFieldException e) { e.printStackTrace(); } /** * 结果: * job type:class java.lang.String * map rawType:interface java.util.Map * map actualTypeArguments: * class java.lang.String, * class java.lang.Integer, */ } }
以上是关于JavaSE---反射(未完待续)的主要内容,如果未能解决你的问题,请参考以下文章