反射机制是什么

反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

反射机制能做什么

反射机制主要提供了以下功能:

  • 在运行时判断任意一个对象所属的类;
  • 在运行时构造任意一个类的对象;
  • 在运行时判断任意一个类所具有的成员变量和方法;
  • 在运行时调用任意一个对象的方法;
  • 生成动态代理。

反射机制的相关API

InterFace 接口

package com.app;

public interface InterFace {

    void read() ;

}

Person 类

package com.app;

public class Person  implements InterFace {

    private String id ;

    private String name ;

    public String age ;

    //构造函数1
public Person( ){ } //构造函数2
public Person( String id ){
this.id = id ;
} //构造函数3
public Person( String id , String name ){
this.id = id ;
this.name = name ;
} public String getId() {
return id;
} public void setId(String id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getAge() {
return age;
} public void setAge(String age) {
this.age = age;
} /**
* 静态方法
*/
public static void update(){ } @Override
public void read() { } }
  • 获取类:3种方法
package com.app;

public class T1 {

    public static void main(String[] args) {

        //第一种方法:forName
try {
Class<?> class1 = Class.forName("com.app.Person"); System.out.println( class1 );
} catch (ClassNotFoundException e) {
e.printStackTrace();
} //第二张方法:class
Class<?> class2 = Person.class; //第三种方法:getClass
Person person = new Person();
Class<?> class3 = person.getClass(); System.out.println( class2 );
System.out.println( class3 );
} }

运行结果:

class com.app.Person
class com.app.Person
class com.app.Person
  • 获取所有的方法:getMethods( )
package com.app;

import java.lang.reflect.Method;

public class T1 {

    public static void main(String[] args) {

        try {
//创建类
Class<?> class1 = Class.forName("com.app.Person"); //获取所有的公共的方法
Method[] methods = class1.getMethods() ; for (Method method : methods) {
System.out.println( method );
} } catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}

运行结果:

//自定义方法
public static void com.app.Person.update()
public java.lang.String com.app.Person.getName()
public void com.app.Person.read()
public java.lang.String com.app.Person.getId()
public void com.app.Person.setName(java.lang.String)
public void com.app.Person.setId(java.lang.String) //父类Object类方法
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
  • 获取所有实现的接口:getInterfaces()
package com.app;

public class T1 {

    public static void main(String[] args) {

        try {
//创建类
Class<?> class1 = Class.forName("com.app.Person"); //获取所有的接口
Class<?>[] interS = class1.getInterfaces() ; for (Class<?> class2 : interS ) {
System.out.println( class2 );
} } catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}

运行结果:

interface com.app.InterFace
  • 获取父类:getSuperclass()
package com.app;

public class T1 {

    public static void main(String[] args) {

        try {
//创建类
Class<?> class1 = Class.forName("com.app.Person"); //获取父类
Class<?> superclass = class1.getSuperclass() ; System.out.println( superclass ); } catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}

运行结果:

//父类是Object类
class java.lang.Object
  • 获取所有的构造函数:getConstructors()
package com.app;

import java.lang.reflect.Constructor;

public class T1 {

    public static void main(String[] args) {

        try {
//创建类
Class<?> class1 = Class.forName("com.app.Person"); //获取所有的构造函数
Constructor<?>[] constructors = class1.getConstructors() ; for (Constructor<?> constructor : constructors) {
System.out.println( constructor );
} } catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}

运行结果:

public com.app.Person(java.lang.String,java.lang.String)
public com.app.Person(java.lang.String)
public com.app.Person()
  • 获取所有的属性:getDeclaredFields();
package com.app;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field; public class T1 { public static void main(String[] args) { try {
//创建类
Class<?> class1 = Class.forName("com.app.Person"); //取得本类的全部属性
Field[] field = class1.getDeclaredFields(); for (Field field2 : field) {
System.out.println( field2 );
} } catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}

运行结果:

private java.lang.String com.app.Person.id
private java.lang.String com.app.Person.name

可以看出属性的修饰符是: private , 数据类型:String ,名字:id/name

  • 创建实例:newInstance()
package com.app;

public class T1 {

    public static void main(String[] args) {

        try {
//创建类
Class<?> class1 = Class.forName("com.app.Person");; //创建实例化:相当于 new 了一个对象
Object object = class1.newInstance() ; //向下转型
Person person = (Person) object ; } catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} }
}

getDeclaredFields 和 getFields 的区别

getDeclaredFields()获得某个类的所有申明的字段,即包括public、private和proteced,但是不包括父类的申明字段。

getFields()获得某个类的所有的公共(public)的字段,包括父类。

小例子

package com.app;

import java.lang.reflect.Field;

public class T1 {

    public static void main(String[] args) {

        try {
//创建类
Class<?> class1 = Class.forName("com.app.Person");; //获得所有的字段属性:包括
Field[] declaredFields = class1.getDeclaredFields() ; Field[] fields = class1.getFields() ; for( Field field : declaredFields ){
System.out.println( "de-- " + field );
} for( Field field : fields ){
System.out.println( "fields-- " + field );
} } catch (ClassNotFoundException e) {
e.printStackTrace();
} }
}

运行结果:

de--  private java.lang.String com.app.Person.id
de-- private java.lang.String com.app.Person.name
de-- public java.lang.String com.app.Person.age
fields-- public java.lang.String com.app.Person.age

实战1:通过反射,获取对象实例,并且操作对象的方法

package com.app;

public class T1 {

    public static void main(String[] args) {

        try {
//创建类
Class<?> class1 = Class.forName("com.app.Person");; //创建实例化:相当于 new 了一个对象
Object object = class1.newInstance() ; //向下转型
Person person = (Person) object ; person.setId( "100");
person.setName( "jack") ; System.out.println( "id: " + person.getId() + " name: " + person.getName() ); } catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} }
}

运行结果:

id: 100 name: jack

实战2:通过反射获取对象字段属性,并且赋值

package com.app;

import java.lang.reflect.Field;

public class T1 {

    public static void main(String[] args) {

        try {
//创建类
Class<?> class1 = Class.forName("com.app.Person"); //创建实例
Object person = class1.newInstance(); //获得id 属性
Field idField = class1.getDeclaredField( "id" ) ; //给id 属性赋值
idField.set( person , "100") ; //打印 person 的属性值
System.out.println( idField.get( person )); } catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace() ;
} catch (ClassNotFoundException e) {
e.printStackTrace();
} }
}

运行结果:

java.lang.IllegalAccessException: Class com.app.T1 can not access a member of class com.app.Person with modifiers "private"
at sun.reflect.Reflection.ensureMemberAccess(Unknown Source)
at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(Unknown Source)
at java.lang.reflect.AccessibleObject.checkAccess(Unknown Source)
at java.lang.reflect.Field.set(Unknown Source)
at com.app.T1.main(T1.java:20)

程序崩溃,原因是:id 这个属性的是 private 私有的,不能修改它的值。

改进:

添加 idField.setAccessible( true );

完整的代码为:

package com.app;

import java.lang.reflect.Field;

public class T1 {

    public static void main(String[] args) {

        try {
//创建类
Class<?> class1 = Class.forName("com.app.Person"); //创建实例
Object person = class1.newInstance(); //获得id 属性
Field idField = class1.getDeclaredField( "id" ) ; //打破封装 实际上setAccessible是启用和禁用访问安全检查的开关,并不是为true就能访问为false就不能访问
//由于JDK的安全检查耗时较多.所以通过setAccessible(true)的方式关闭安全检查就可以达到提升反射速度的目的
idField.setAccessible( true ); //给id 属性赋值
idField.set( person , "100") ; //打印 person 的属性值
System.out.println( idField.get( person )); } catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace() ;
} catch (ClassNotFoundException e) {
e.printStackTrace();
} }
}

运行结果:

100

实战3:综合训练,反射操作属性和方法

package com.app;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; public class T1 { public static void main(String[] args) { try {
//创建类
Class<?> class1 = Class.forName("com.app.Person"); //创建实例
Object person = class1.newInstance(); //获得id 属性
Field idField = class1.getDeclaredField( "id" ) ; //打破封装 实际上setAccessible是启用和禁用访问安全检查的开关,并不是为true就能访问为false就不能访问
//由于JDK的安全检查耗时较多.所以通过setAccessible(true)的方式关闭安全检查就可以达到提升反射速度的目的
idField.setAccessible( true ); //给id 属性赋值
idField.set( person , "100") ; //获取 setName() 方法
Method setName = class1.getDeclaredMethod( "setName", String.class ) ;
//打破封装
setName.setAccessible( true ); //调用setName 方法。
setName.invoke( person , "jack" ) ; //获取name 字段
Field nameField = class1.getDeclaredField( "name" ) ;
//打破封装
nameField.setAccessible( true ); //打印 person 的 id 属性值
String id_ = (String) idField.get( person ) ;
System.out.println( "id: " + id_ ); //打印 person 的 name 属性值
String name_ = ( String)nameField.get( person ) ;
System.out.println( "name: " + name_ ); //获取 getName 方法
Method getName = class1.getDeclaredMethod( "getName" ) ;
//打破封装
getName.setAccessible( true ); //执行getName方法,并且接收返回值
String name_2 = (String) getName.invoke( person ) ;
System.out.println( "name2: " + name_2 ); } catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace() ;
} catch (ClassNotFoundException e) {
e.printStackTrace();
} }
}

运行结果:

id: 100
name: jack
name2: jack

实战4:静态属性、静态方法调用

定义 Util 类

package com.app;

public class Util {

    public static String name = "json" ;

    /**
* 没有返回值,没有参数
*/
public static void getTips(){
System.out.println( "执行了---------1111");
} /**
* 有返回值,没有参数
*/
public static String getTip(){
System.out.println( "执行了---------2222");
return "tip2" ;
} /**
* 没有返回值,有参数
* @param name
*/
public static void getTip( String name ){
System.out.println( "执行了---------3333 参数: " + name );
} /**
* 有返回值,有参数
* @param id
* @return
*/
public static String getTip( int id ){
System.out.println( "执行了---------4444 参数: " + id );
if ( id == 0 ){
return "tip1 444 --1 " ;
}else{
return "tip1 444 --2" ;
}
} }

完整小例子:

package com.app;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; public class T1 { public static void main(String[] args) { try {
//创建类
Class<?> class1 = Class.forName("com.app.Util"); //获取 nameField 属性
Field nameField = class1.getDeclaredField( "name" ) ;
//获取 nameField 的值
String name_ = (String) nameField.get( nameField ) ;
//输出值
System.out.println( name_ ); //没有返回值,没有参数
Method getTipMethod1 = class1.getDeclaredMethod( "getTips" ) ;
getTipMethod1.invoke( null ) ; //有返回值,没有参数
Method getTipMethod2 = class1.getDeclaredMethod( "getTip" ) ;
String result_2 = (String) getTipMethod2.invoke( null ) ;
System.out.println( "返回值: "+ result_2 ); //没有返回值,有参数
Method getTipMethod3 = class1.getDeclaredMethod( "getTip" , String.class ) ;
String result_3 = (String) getTipMethod3.invoke( null , "第三个方法" ) ;
System.out.println( "返回值: "+ result_3 ); //有返回值,有参数
Method getTipMethod4 = class1.getDeclaredMethod( "getTip" , int.class ) ;
String result_4 = (String) getTipMethod4.invoke( null , 1 ) ;
System.out.println( "返回值: "+ result_4 ); } catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace() ;
} catch (ClassNotFoundException e) {
e.printStackTrace();
} }
}

运行结果:

json
执行了---------1111
执行了---------2222
返回值: tip2
执行了---------3333 参数: 第三个方法
返回值: null
执行了---------4444 参数: 1
返回值: tip1 444 --2

当参数是 int 类型 和 Integer 类型,反射获取方法不一样

  • 当参数是 int 类型时
    /**
* 没有返回值,有参数
* @param id
*/
public static void getTip( int id ){ }

获取方法的时候需要用:int.class。不能使用 Integer.class. 会报错。

Method getTipMethod4 = class.getDeclaredMethod( "getTip" , int.class ) ;
String result_4 = (String) getTipMethod4.invoke( null , 1 ) ;
System.out.println( "返回值: "+ result_4 );
  • 当参数是 Integer类型时
    /**
* 没有返回值,有参数
* @param id
*/
public static void getTip( Integer id ){ }

获取方法的时候需要用:Integer .class。不能使用 int.class. 会报错。

Method getTipMethod4 = class.getDeclaredMethod( "getTip" , Integer .class ) ;
String result_4 = (String) getTipMethod4.invoke( null , 1 ) ;
System.out.println( "返回值: "+ result_4 );

创建对象实例

Person 类

package com.app;

public class Person{

    private String id ;

    private String name ;

    //构造函数1
public Person( ){
System.out.println( "构造函数 无参" );
} //构造函数2
public Person( String id ){
this.id = id ;
System.out.println( "构造函数 id : " + id );
} //构造函数3
public Person( String id , String name ){
this.id = id ;
this.name = name ;
System.out.println( "构造函数 id : " + id + " name: " + name );
} public String getId() {
return id;
} public void setId(String id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} }

创建实例实战

package com.app;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException; public class T1 { public static void main(String[] args) { try { //创建类
Class<?> class1 = Class.forName("com.app.Person"); //无参构造函数
Object object = class1.newInstance() ; //有参构造函数:一个参数
Constructor<?> constructor = class1.getDeclaredConstructor( String.class ) ;
constructor.newInstance( "1000" ) ; //有参构造函数:二个参数
Constructor<?> constructor2 = class1.getDeclaredConstructor( String.class , String.class ) ;
constructor2.newInstance( "1001" , "jack" ) ; } catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace() ;
} catch (ClassNotFoundException e) {
e.printStackTrace();
} }
}

运行结果

构造函数  无参
构造函数 id : 1000
构造函数 id : 1001 name: jack

总结

  • Class类提供了四个public方法,用于获取某个类的构造方法。
Constructor getConstructor(Class[] params)     根据构造函数的参数,返回一个具体的具有public属性的构造函数
Constructor getConstructors() 返回所有具有public属性的构造函数数组
Constructor getDeclaredConstructor(Class[] params) 根据构造函数的参数,返回一个具体的构造函数(不分public和非public属性)
Constructor getDeclaredConstructors() 返回该类中所有的构造函数数组(不分public和非public属性)
  • 四种获取成员方法的方法
Method getMethod(String name, Class[] params)    根据方法名和参数,返回一个具体的具有public属性的方法
Method[] getMethods() 返回所有具有public属性的方法数组
Method getDeclaredMethod(String name, Class[] params) 根据方法名和参数,返回一个具体的方法(不分public和非public属性)
Method[] getDeclaredMethods() 返回该类中的所有的方法数组(不分public和非public属性)
  • 四种获取成员属性的方法
Field getField(String name)    根据变量名,返回一个具体的具有public属性的成员变量
Field[] getFields() 返回具有public属性的成员变量的数组
Field getDeclaredField(String name) 根据变量名,返回一个成员变量(不分public和非public属性)
Field[] getDelcaredField() 返回所有成员变量组成的数组(不分public和非public属性)

Java 反射简介(转载)的更多相关文章

  1. Java反射简介

    Java反射简介 1.Class类 1) 在面向对象的世界里,万事万物皆对象.(java语言中,静态的成员.普通数据类型除外) 类是不是对象呢?类是(哪个类的对象呢?)谁的对象呢? 类是对象,类是ja ...

  2. Java 反射简介

    本文部分内容参考博客.点击链接可以查看原文. 1. 反射的概念 反射是指在运行时将类的属性.构造函数和方法等元素动态地映射成一个个对象.通过这些对象我们可以动态地生成对象实例,调用类的方法和更改类的属 ...

  3. 理解Java反射机制

    理解Java反射机制 转载请注明出处,谢谢! 一.Java反射简介 什么是反射? Java的反射机制是Java特性之一,反射机制是构建框架技术的基础所在.灵活掌握Java反射机制,对学习框架技术有很大 ...

  4. java反射机制梳理

    java反射机制梳理 Java反射简介 反射简介 编译和运行 编译时刻加载类是静态加载类.运行时刻加载类是动态加载类 要让Java程序能够运行,那么就得让Java类要被Java虚拟机加载.Java类如 ...

  5. Java 反射 设计模式 动态代理机制详解 [ 转载 ]

    Java 反射 设计模式 动态代理机制详解 [ 转载 ] @author 亦山 原文链接:http://blog.csdn.net/luanlouis/article/details/24589193 ...

  6. Java基础—反射(转载)

    转载自: JAVA反射与注解 JAVA反射 主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义. 反射机制是什么 反射 ...

  7. 【转载】Java 反射详解

    目录 1.什么是反射? 2.反射能做什么? 3.反射的具体实现 4.根据反射获取父类属性 4.反射总结 反射反射,程序员的快乐! 1.什么是反射? Java反射就是在运行状态中,对于任意一个类,都能够 ...

  8. Java 反射(一)反射简介、原理和应用场景

    目录 一.动态语言和动态语言的比较 动态语言 静态语言 二.反射 简介 反射的常见使用 1. 代码编辑器 2. Spring等框架的IoC容器 3. 和注解的配合使用 原理 反射优缺点 调试查看 Cl ...

  9. 【转载】Java反射: 数组

    原创链接:http://czj4451.iteye.com/blog/1479486 java.lang.reflect.Array Java反射机制通过Array类来处理数组,结合java.lang ...

随机推荐

  1. jQuery基础--选择器

    2. 选择器 2.1. 什么是jQuery选择器 jQuery选择器是jQuery为我们提供的一组方法,让我们更加方便的获取到页面中的元素.注意:jQuery选择器返回的是jQuery对象. jQue ...

  2. android测试开发概念

    一:测试分类 1.分类概览 按测试阶段划分: 单元测试 集成测试 系统测试 验收测试 按是否覆盖源代码: 黑盒测试: 功能测试: 界面测试 逻辑测试 安装测试 应用性测试 兼容性测试 性能测试: 稳定 ...

  3. 【五一qbxt】day7-1 引水入城

    [noip2010 洛谷p1514]引水入城 Before: 线段覆盖问题#1:(我们所需要的) 一个区间,若干条线段,现在求最少多少条线段覆盖满整个区间 区间长度8,可选的覆盖线段[2,6],[1, ...

  4. UVALive 6270 Edge Case(找规律,大数相加)

    版权声明:本文为博主原创文章,未经博主同意不得转载. vasttian https://blog.csdn.net/u012860063/article/details/36905379 转载请注明出 ...

  5. Source Insight symbol not found

    使用SourceInsight查看源代码时,发现点击查看相关类型时,无法关联到其代码,出现 symbol not found, 然而明明在我的头文件有定义的 网上查了一下主要是因为新建工程导入文件后, ...

  6. CAS无锁策略

    并发编程时,对于共享资源的使用需要确保绝对的安全性.除了利用锁机制之外,还有一种无锁的概念.所谓无锁,就是假定在并发情况下,对于共享资源的访问没有冲突,线程可以一直不停的运行,无需阻塞,如果产生冲突, ...

  7. 脚本_检测 MySQL 数据库连接数量

    #!bin/bash#功能:检测 MySQL数据库连接数量,以满足对 MySQL 数据库的监控需求,查看 MySQL 连接是否正常.#作者:liusingbon#本脚本每 2 秒检测一次 MySQL ...

  8. Android学习电子书

           

  9. wait()和sleep()、sleep()和yield()的区别

    wait()和sleep()的区别主要表现在一下几个方面: 原理不同.sleep()方法是Thread类的静态方法,是线程用来控制自身流程的.它会使线程暂停执行一段时间,把执行机会让给其他线程,等到时 ...

  10. [USACO06FEB]摊位预订Stall Reservations(贪心)

    [USACO06FEB]摊位预订Stall Reservations 题目描述 Oh those picky N (1 <= N <= 50,000) cows! They are so ...