Java——反射机制
来源:互联网 发布:打条码软件 编辑:程序博客网 时间:2024/05/16 09:49
反射概念:
Java反射是Java被视为动态(或准动态)语言的一个关键性质。这个机制允许程序在运行时透过Reflection APIs取得任何一个已知名称的class的内部信息,包括其modifiers(诸如public, static 等)、superclass(例如Object)、实现之interfaces(例如Cloneable),也包括fields和methods的所有信息,并可于运行时改变fields内容或唤起methods。
Java反射机制容许程序在运行时加载、探知、使用编译期间完全未知的classes。
换言之,Java可以加载一个运行时才得知名称的class,获得其完整结构。
反射是Java中一种强大的工具,能够使我们很方便的创建灵活的代码,这些代码可以再运行时装配,无需在组件之间进行源代码链接。但是反射使用不当会成本很高!
JAVA反射机制提供了什么功能
提供了如下功能:
- 在运行时判断任意一个对象所属的类
- 在运行时构造任意一个类的对象
- 在运行时判段任意一个类所具有的成员变量和方法
- 在运行时调用任一个对象的方法
- 在运行时创建新类对象
- 在使用Java的反射功能时,基本首先都要获取类的Class对象,再通过Class对象获取其他的对象。
反射机制的作用:
- 反编译:.class–>.java
- 通过反射机制访问java对象的属性,方法,构造方法等;
Java中JDK提供的Reflection API
Java反射相关的API在包java.lang.reflect中。
Member接口 该接口可以获取有关类成员(域或者方法)后者构造函数的信息。
AccessibleObject类 该类是域(field)对象、方法(method)对象、构造函数(constructor)对象的基础类。它提供了将反射的对象标记为在使用时取消默认
Java 语言访问控制检查的能力。 Array类 该类提供动态地生成和访问JAVA数组的方法。
Constructor类 提供一个类的构造函数的信息以及访问类的构造函数的接口。 Field类 提供一个类的域的信息以及访问类的域的接口。
Method类 提供一个类的方法的信息以及访问类的方法的接口。
Modifier类 提供了 static方法和常量,对类和成员访问修饰符进行解码。
Proxy类 提供动态地生成代理类和类实例的静态方法。
动态创建代理类
代理模式:代理模式的作用=为其他对象提供一种代理以控制对这个对象的访问。
代理模式的角色:
- 抽象角色:声明真实对象和代理对象的共同接口
- 代理角色:代理角色内部包含有真实对象的引用,从而可以操作真实对象。
- 真实角色:代理角色所代表的真实对象,是我们最终要引用的对象。
动态代理:
- java.lang.reflect.Proxy
Proxy 提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类 - InvocationHandler
是代理实例的调用处理程序 实现的接口,每个代理实例都具有一个关联的调用处理程序。对代理实例调用方法时,将对方法调用进行编码并将其指派到它的调用处理程序的 invoke 方法。
动态Proxy是这样的一种类:
它是在运行生成的类,在生成时你必须提供一组Interface给它,然后该class就宣称它实现了这些interface。你可以把该class的实例当作这些interface中的任何一个来用。当然,这个Dynamic Proxy其实就是一个Proxy,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作。
在使用动态代理类时,我们必须实现InvocationHandler接口
实例练习:
import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.List;public class InvokeTest { /** * 利用反射机制实现调用方法 * @param obj * @param methodName * @throws NoSuchMethodException * @throws SecurityException * @throws IllegalAccessException * @throws IllegalArgumentException * @throws InvocationTargetException */ public static void test(String methodName) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { InvokeTest test=new InvokeTest(); //对象类型 Class<?> cls=test.getClass(); //利用反射机制获取该类型下的方法 Method method=cls.getMethod(methodName, int.class,String.class); //执行该方法 method.invoke(test, 10,"20");// test.method(10,20) } /** * ...代表:一组相同类型的数据(不约束个数) * 一个方法里最多只能有一个...类型 * ...类型必须出现在参数列表的最后位置 * @param a */ public static void e(int... a) { for(int i=0;i<a.length;i++) { System.out.println(a[i]); } } //反射机制 //调用方法 //不知道方法名或属性名 //通过传递参数来实现调用 public static void main(String[] args) { //...省略参数类型 e(1,2,3,4,5); //反射机制 try { test("d"); } catch (NoSuchMethodException e) { // TODO Auto-generated catch block //没有该方法 e.printStackTrace(); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void a() { System.out.println("aaaaaaaaaa"); } public void b(int b) { System.out.println("b="+b); } public void c(int a,int b) { System.out.println("sum="+(a+b)); } public void d(int a,String b) { System.out.println(a+b); }
具体功能的实现
反射机制获取类有三种方法,我们来获取Employee类型。
//第一种方式: Classc1 = Class.forName("Employee"); //第二种方式: //java中每个类型都有class 属性. Classc2 = Employee.class; //第三种方式: //java语言中任何一个java对象都有getClass 方法 Employeee = new Employee(); Classc3 = e.getClass(); //c3是运行时类 (e的运行时类是Employee)
创建对象:获取类以后我们来创建它的对象,利用newInstance:
Class c =Class.forName("Employee"); //创建此Class 对象所表示的类的一个新实例 Objecto = c.newInstance(); //调用了Employee的无参数构造方法.
获取属性:分为所有的属性和指定的属性:
a,先看获取所有的属性的写法:
//获取整个类 Class c = Class.forName("java.lang.Integer"); //获取所有的属性? Field[] fs = c.getDeclaredFields(); //定义可变长的字符串,用来存储属性 StringBuffer sb = new StringBuffer(); //通过追加的方法,将每个属性拼接到此字符串中 //最外边的public定义 sb.append(Modifier.toString(c.getModifiers()) + " class " + c.getSimpleName() +"{\n"); //里边的每一个属性 for(Field field:fs){ sb.append("\t");//空格 sb.append(Modifier.toString(field.getModifiers())+" ");//获得属性的修饰符,例如public,static等等 sb.append(field.getType().getSimpleName() + " ");//属性的类型的名字 sb.append(field.getName()+";\n");//属性的名字+回车 } sb.append("}"); System.out.println(sb);
b,获取特定的属性,对比着传统的方法来学习:
public static void main(String[] args) throws Exception{ <span style="white-space:pre"> </span>//以前的方式: /* User u = new User(); u.age = 12; //set System.out.println(u.age); //get */ //获取类 Class c = Class.forName("User"); //获取id属性 Field idF = c.getDeclaredField("id"); //实例化这个类赋给o Object o = c.newInstance(); //打破封装 idF.setAccessible(true); //使用反射机制可以打破封装性,导致了java对象的属性不安全。 //给o对象的id属性赋值"110" idF.set(o, "110"); //set //get System.out.println(idF.get(o)); }
参考博客:
博客1:
http://blog.csdn.net/liujiahan629629/article/details/18013523
博客2:
http://blog.csdn.net/yongjian1092/article/details/7364451
- Java—反射机制
- JAVA——反射机制
- java——反射机制
- Java——反射机制
- java原理—反射机制
- Java基础—反射机制
- java原理—反射机制
- Java学习—— Java反射机制
- java基础知识—Java中的反射机制
- Java反射机制——反射的介绍(一)
- Java———反射机制
- java之反射机制——invoke。
- java反射机制——解析
- JAVA加强——反射机制
- 黑马程序员——Java 反射机制
- JAVA高新技术——反射机制Reflection
- 黑马程序员——-Java反射机制-
- 黑马程序员——java反射机制
- 市场上各种深度摄像头测试之OPT8241
- Winform 刷新闪烁
- unity中EventSystem射线检测结果的排序规则
- redis集群实现(五) sentinel的架构与raft协议
- SpringMVC笔记——SSM框架搭建简单实例
- Java——反射机制
- bootstrap中table隐藏后显示问题
- 隐藏滚动条
- SQLSERVER CDC 功能
- (根据指定时间)动态划分学期分表,用以动态学期分表自动CURD等联动操作(开始结束时间可修改-待完善待修改)
- 总结命令行07:MySQL
- 转自 kyo_san 为什么不能同时满足CAP原则
- 01 Spring框架 基本介绍
- 第11讲项目4-玩数字