反射概念:

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——反射机制的更多相关文章

  1. 第28章 java反射机制

    java反射机制 1.类加载机制 1.1.jvm和类 运行Java程序:java 带有main方法的类名 之后java会启动jvm,并加载字节码(字节码就是一个类在内存空间的状态) 当调用java命令 ...

  2. Java反射机制

    Java反射机制 一:什么事反射机制 简单地说,就是程序运行时能够通过反射的到类的所有信息,只需要获得类名,方法名,属性名. 二:为什么要用反射:     静态编译:在编译时确定类型,绑定对象,即通过 ...

  3. java基础知识(十一)java反射机制(上)

    java.lang.Class类详解 java Class类详解 一.class类 Class类是java语言定义的特定类的实现,在java中每个类都有一个相应的Class对象,以便java程序运行时 ...

  4. java基础知识(十一)java反射机制(下)

    1.什么是反射机制? java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象都能够调用他的属性和方法,这种动态获取属性和方法的功能称为java的反射机制. ...

  5. Java反射机制专题

    ·Java Reflection Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方 ...

  6. java反射机制深入详解

    java反射机制深入详解  转自:http://www.cnblogs.com/hxsyl/archive/2013/03/23/2977593.html 一.概念 反射就是把Java的各种成分映射成 ...

  7. Java反射机制DOME

    Java反射机制 public class TestHibernate { @Test public void TestHb(){ try { Class cs = Class.forName(&qu ...

  8. 反射——Java反射机制

    反射概述 什么是反射? ①   反射的概念是由Smith在1982年首次提出的,主要指程序可以访问.检测和修改它本身状态或行为的一种能力. ②   JAVA反射机制是在运行状态中,对应任意一个类,都能 ...

  9. Java反射机制可以动态修改实例中final修饰的成员变量吗?

    问题:Java反射机制可以动态修改实例中final修饰的成员变量吗? 回答是分两种情况的. 1. 当final修饰的成员变量在定义的时候就初始化了值,那么java反射机制就已经不能动态修改它的值了. ...

  10. Java反射机制学习与研究

    Java反射机制:可以获取正在运行时的Java对象. 1.判断运行时对象对象所属的类. 2.判断运行时对象所具有的成员变量和方法. 3.还可以调用到private方法,改变private变量的值. S ...

随机推荐

  1. 分享知乎关于pull request的分享

    作者:知乎用户链接:https://www.zhihu.com/question/21682976/answer/79489643来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注 ...

  2. 建立索引和创建视图(结合YGGL.sql)

    一.请按要求对YGGL库建立相关索引 (1)使用create index 语句创建索引 1.对employees表中的员工部门号创建普通索引depart_ind. mysql> create i ...

  3. tf.lin_space

    .lin_spae{ start, stop, num, name=None } start:张量(float32,或者float64类型) stop:张量(和start相同) num:张量(int3 ...

  4. .NET Core 中的日志与分布式链路追踪

    目录 .NET Core 中的日志与分布式链路追踪 .NET Core 中的日志 控制台输出 非侵入式日志 Microsoft.Extensions.Logging ILoggerFactory IL ...

  5. CentOS7 普通用户绕过root登录

      正常环境中我们的服务器都会使用一个普通用户跳转到root进行操作,如果root用户的密码不记得只知道普通用户密码,设备又不方便进行开关机破密码时,我们就可以用到以下方法登陆设备. pkexec : ...

  6. 【详细】Python基础(一)

    @ 目录 前言 1. Python环境的搭建 1.1 python解释器的安装 1.2 pycharm的安装 2. Python基础语法 2.1 基本语法 2.2 数据类型 2.3 标识符与关键字 2 ...

  7. SpringBoot整合Shiro完成验证码校验

    SpringBoot整合Shiro完成验证码校验 上一篇:SpringBoot整合Shiro使用Redis作为缓存 首先编写生成验证码的工具类 package club.qy.datao.utils; ...

  8. Java内存模型与线程(二)线程的实现和线程的调度

    先行先发生原则(happen-before原则) 先行先发生是指Java内存模型中定义的两项操作之间的偏序关系. 如果说A先行于B,其实就是说在发生B操作之前,操作A产生的影响能被操作B观察到,至于这 ...

  9. AttGAN: Facial Attribute Editing by Only Changing What You Want 论文阅读笔记和AttGan的pytorch代码实现

    1.总体框架 上面的过程用详细描述即是 Test阶段: Train阶段: 由于我们无法得知编辑后的image,所以显而易见人脸属性编辑是一个无监督问题,而对于我们的xa需要获得关于b的属性,故利用at ...

  10. DHCP最佳实践(一)

    这是Windows DHCP最佳实践和技巧的最终指南. 如果您有任何最佳做法或技巧,请在下面的评论中发布它们. 在本指南(一)中,我将分享以下DHCP最佳实践和技巧. 不要将DHCP放在您的域控制器上 ...