反射概念:

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. druid监控

    1 @ConfigurationProperties(prefix = "spring.datasource") 2 @Bean 3 public DataSource druid ...

  2. sql删除重复数据思路

    总的思路就是先找出表中重复数据中的一条数据,插入临时表中,删除所有的重复数据,然后再将临时表中的数据插入表中.所以重点是如何找出重复数据中的一条数据,有三种情况 1.重复数据完全一样,使用distin ...

  3. Dota游戏匹配的所有组合

    在Dota游戏中有一种匹配玩法,任意5人以下玩家组队,加入匹配系统,由系统组合出5人 vs 5人的组合进行游戏,比如2人+3人  vs 1人+4人.抽象出这个问题,就变成两边各有m个玩家,最多允许n个 ...

  4. .netcore利用perf分析高cpu使用率

    目录 一 在宿主机运行perf 二 容器内安装perf 1,重新构建镜像 2,下载火焰图生成脚本 3,安装linux-perf 三 CPU占用分析 1,perf record捕获进程 2,生成火焰图 ...

  5. uber_go_guide解析(二)

    前言 接上回 正文 错误消息 Go中声明错误有几种方式 errors.New() 简单的声明静态字符串信息的错误 fmt.Errorf 可以格式化插入信息的错误 自己实现 Error() 方法 使用e ...

  6. python中环境变量的使用

    前言 之前就经常用,今天来凑个篇数. 在开发的过程中,我们经常会将代码中某些可能更改的,比如redis地址,数据库地址,限流阈值等参数写活来提高灵活性, 传统的方式可能是写在配置文件中,比如 xml ...

  7. 【SpringBoot1.x】SpringBoot1.x 数据访问

    SpringBoot1.x 数据访问 简介 对于数据访问层,无论是 SQL 还是 NOSQL,Spring Boot 默认采用整合 Spring Data 的方式进行统一处理,添加大量自动配置,屏蔽了 ...

  8. LeetCode374 猜数字大小

    我们正在玩一个猜数字游戏. 游戏规则如下:我从 1 到 n 选择一个数字. 你需要猜我选择了哪个数字.每次你猜错了,我会告诉你这个数字是大了还是小了.你调用一个预先定义好的接口 guess(int n ...

  9. 【Linux】E297: Write error in swap file 解决办法

    今天登陆到服务器上,发现通过vi 打开文件就会报错: E297: Write error in swap file E303: Unable to open swap file for "c ...

  10. 缓存淘汰算法 LRU 和 LFU

    LRU (Least Recently Used), 即最近最少使用用算法,是一种常见的 Cache 页面置换算法,有利于提高 Cache 命中率. LRU 的算法思想:对于每个页面,记录该页面自上一 ...