JAVA反射实践

Java反射机制在我的理解当中就是下面几点:

1. 对一个给定的类名(以字符串形式提供)能动态构建一个对象实例

2. 对于任意一个类,都能够知道这个类的所有属性和方法

3. 对于任意一个对象,都能够调用它的任意一个方法和属性;

这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制,这种反射机制在Java当中给我们带来了极大的方便,被大量地应用于JavaBean中

在Java的反射中我们主要用到以下几个类,下面将逐个说明

  1. java.lang.Class;
  2. java.lang.reflect.Constructor;
  3. java.lang.reflect.Field;
  4. java.lang.reflect.Method;
  5. java.lang.reflect.Modifier;

1.java.lang.Class类:用于保存每个对象所属类的相关信息,在Java中,Object类中的getClass()方法将会返回一个Class类型的实例,(注意:记住这是一个类,和关键字class完全是两码事)

2.java.lang.reflect.Constructor:提供关于类的单个构造方法的信息以及对它的访问权限。

3.java.lang.reflect.Field:提供有关类或接口的单个字段的信息,以及对它的动态访问权限

4.java.lang.reflect.Method:提供关于类或接口上单独某个方法(以及如何访问该方法)的信息。所反映的方法可能是类方法或实例方法(包括抽象方法)。

5.java.lang.reflect.Modifier:提供了类、类的成员、static方法、常量的修饰符。

public class Person {
	// Field
	private String person_name;
	protected int person_age;
	public boolean person_sex;

	// Construct
	public Person() {
		super();
	}

	public Person(String name, int age, boolean sex) {
		super();
		this.setPerson_name(name);
		this.person_age = age;
		this.person_sex = sex;
	}

	// Method
	public void AddAge(int year) {
		this.person_age += this.person_age + year;
	}

	public String getPerson_name() {
		return person_name;
	}

	public void setPerson_name(String person_name) {
		this.person_name = person_name;
	}
}
public class Employee extends Person{
	private double saray;
	protected String gangwei;

	public Employee() {
		super();
	}

	public Employee(double saray, String gangwei) {
		super();
		this.saray = saray;
		this.gangwei = gangwei;
	}

	public double getSaray() {
		return saray;
	}

	public void setSaray(double saray) {
		this.saray = saray;
	}

	public String getGangwei() {
		return gangwei;
	}

	public void setGangwei(String gangwei) {
		this.gangwei = gangwei;
	}

	public void addSaray(double money){
		this.saray+=money;
	}

}

以下按照我们常用的方法介绍下使用方法:

1.根据类名构造一个实例

		// 根据类名获取Class对象
		Class c = Class.forName("Employee");
		System.out.println(c.getName()); // 此处打印:Employee
		// 获取父类Class对象
		Class cp = c.getSuperclass();
		System.out.println(cp.getName());// 此处打印:Person
		// 获取类的访问修饰符
		String modifiers = Modifier.toString(c.getModifiers());
		System.out.println(modifiers); // 此处打印:public
		// 实例化
		Object obj = c.newInstance(); //通过无参的构造函数进行实例化

2.获取类的Field,主要有以下四个方法

Class c = Class.forName("Employee");

  • c.getField(name) ;
  • c.getFields()
  • c.getDeclaredFields()
  • c.getDeclaredField(name)

getField()方法返回这个类或其超类的公有字段(不包括private和protect修饰的字段)

getDeclaredField方法返回这个类的全部字段(包括private和protect修饰的字段)

<span style="white-space:pre">		</span>/*
		 * 获取类Employee的所有Field
		 *
		 * c.getField(name) c.getFields() c.getDeclaredFields()
		 * c.getDeclaredField(name)
		 */
		Field[] fields = c.getDeclaredFields();
		for (Field f : fields) {
			// 获取该Field的类型
			Class type = f.getType();
			// 获取该Field的名称
			String name = f.getName();
			// 获取该Field的访问修饰符
			String sFieldModifiers = Modifier.toString(f.getModifiers());
			System.out.println(sFieldModifiers + " " + type.getName() + " " + name + ";");
		}


3.获取类的构造函数

同Field一样,获取构造函数也有4个方法

  • * c.getDeclaredConstructors()
  • * c.getConstructors()
  • * c.getDeclaredConstructor(parameterTypes)
  • * c.getDeclaredConstructor(parameterTypes)
<span style="white-space:pre">		</span>/*
		 * 获取类的构造函数
		 * c.getDeclaredConstructors()
		 * c.getConstructors()
		 * c.getDeclaredConstructor(parameterTypes)
		 * c.getDeclaredConstructor(parameterTypes)
		 */
		Constructor[] constructors = c.getDeclaredConstructors();
		for (Constructor cr : constructors) {
			// 构造函数名称
			String name = cr.getName();
			// 构造函数修饰符
			String sConstructorModifiers = Modifier.toString(cr.getModifiers());
			// 构造函数参数
			Class[] paramTypes = cr.getParameterTypes();
			String sParam = "";
			for (int j = 0; j < paramTypes.length; j++) {
				if (j > 0)
					sParam += ", ";
				sParam += paramTypes[j].getName();
			}
			System.out.println(sConstructorModifiers + " " + name + "(" + sParam + ");");
		}

4.获取类的Method

同Field一样,有4个获取方法的方法,另外多了一个方法,用于获取返回类型

<span style="white-space:pre">		Method[] methods = c.getDeclaredMethods();
<span style="white-space:pre">		</span>for (Method m : methods) {
<span style="white-space:pre">			</span>// 方法返回类型
<span style="white-space:pre">			</span>Class returnType = m.getReturnType();
<span style="white-space:pre">			</span>String sReturnType = returnType.toString();
<span style="white-space:pre">			</span>// 方法名称
<span style="white-space:pre">			</span>String name = m.getName();
<span style="white-space:pre">			</span>// 方法修饰符
<span style="white-space:pre">			</span>String sMethodModifiers = Modifier.toString(m.getModifiers());
<span style="white-space:pre">			</span>// 方法参数
<span style="white-space:pre">			</span>Class[] paramTypes = m.getParameterTypes();
<span style="white-space:pre">			</span>String sParam = "";
<span style="white-space:pre">			</span>for (int j = 0; j < paramTypes.length; j++) {
<span style="white-space:pre">				</span>if (j > 0)
<span style="white-space:pre">					</span>sParam += ", ";
<span style="white-space:pre">				</span>sParam += paramTypes[j].getName();
<span style="white-space:pre">			</span>}
<span style="white-space:pre">			</span>System.out.println(sMethodModifiers + " " + sReturnType + " " + name + "(" + sParam + ");");
<span style="white-space:pre">		</span>}</span>

5.利用反射动态给对象属性赋值,比如我们需要从配置文件中读取某个员工的信息,并赋值给某个对象,我们可以这样写:

<span style="white-space:pre">		</span>/*
<span style="white-space:pre">		</span> * 动态给类的属性赋值
<span style="white-space:pre">		</span> */
<span style="white-space:pre">		</span>Class c2 = Class.forName("Employee");
<span style="white-space:pre">		</span>Object e = c2.newInstance();
<span style="white-space:pre">		</span>Field f = c2.getDeclaredField("saray");
<span style="white-space:pre">		</span>// 因为属性saray是private的,所有需要调用setAccessible方法才能给该属性赋值,否则报错
<span style="white-space:pre">		</span>f.setAccessible(true);
<span style="white-space:pre">		</span>f.set(e, 10000);
<span style="white-space:pre">		</span>Field f2 = c2.getDeclaredField("gangwei");
<span style="white-space:pre">		</span>f2.set(e, "高级软件工程师");
<span style="white-space:pre">		</span>System.out.println(((Employee) e).getGangwei() + " " + ((Employee) e).getSaray());
<span style="white-space:pre">		</span>// 取值
<span style="white-space:pre">		</span>Field f3 = c2.getDeclaredField("saray");
<span style="white-space:pre">		</span>Field f4 = c2.getDeclaredField("gangwei");
<span style="white-space:pre">		</span>f3.setAccessible(true);
<span style="white-space:pre">		</span>System.out.println(f3.get(e));
<span style="white-space:pre">		</span>System.out.println(f4.get(e));

输出结果如下:

高级软件工程师 10000.0

10000.0

高级软件工程师

6.利用反射动态地调用对象的方法,比如Employee类中有个addsaray的方法,我们看下要怎么调用:

		Class c3 = Class.forName("Employee");
		Object e3 = c3.newInstance();
		Field fSaray = c3.getDeclaredField("saray");
		fSaray.setAccessible(true);
		fSaray.set(e3, 10000);
		System.out.println(fSaray.get(e3)); //输出10000
		// 获取Method
		Method m = c3.getDeclaredMethod("addSaray", double.class);
		/*
		 * Method m = c3.getDeclaredMethod("addSaray"); Method m2 =
		 * c3.getDeclaredMethod("addSaray", double.class);
		 * 如果有多个重名的方法,要添加参数让编译器知道应该调用哪个方法,这里只有一个参数,所以上面两种写法都可以
		 */
		// 调用方法
		m.invoke(e3, 5000);
		System.out.println(fSaray.get(e3)); //输出15000,因此证明方法调用成功

输出结果如下:

10000.0

15000.0

时间: 2024-10-21 12:34:40

JAVA反射实践的相关文章

java 反射实践

/** * * @author yuxg */ import coreJava.javaFile; import javaClassStudy.Student; import javaClassStudy.Person; public class helloWorld { public static void main(String[] parm){ //reflection //实例一个学生对象 Person p = new Student("yuxg",12); //获取对象的类

java反射的应用实践

java反射之前接触比较多,但仅技术方面思考的多:这次主要是从业务角度出发,思考java反射在业务模块设计中如何发挥更高效的作用,以提高生产率. 1.业务需求 要处理银行回单票据,提取出付款人.收款人及对应银行和业务信息,每个银行的格式都不统一.所以需要对各家银行的格式进行预处理,规整为标准格式后,交由后续模块处理. 这个预处理格式化的设计有多种 2.方案选型 做法 适用场景 技能要求 在if..else中添加分支逻辑 适用于分支较少的场景,如只有2~4个 简单 把分支逻辑提取为句柄,显示注册到

java反射基础知识(五)反射应用实践

详解Java反射各种应用 Java除了给我们提供在编译期得到类的各种信息之外,还通过反射让我们可以在运行期间得到类的各种信息.通过反射获取类的信息,得到类的信息之后,就可以获取以下相关内容: Class对象 构造器 变量 方法 私有变量与私有方法 注解 泛型 数组 本文也将从上面几个方面来介绍Java反射.本文涉及的所有代码均在反射代码首先放出一个Java类作为反射的研究对象,类的内容如下: public abstract class FatherObject implements Runnab

java 反射 详解

本文来自:blog.csdn.net/ljphhj JAVA反射机制:   通俗地说,反射机制就是可以把一个类,类的成员(函数,属性),当成一个对象来操作,希望读者能理解,也就是说,类,类的成员,我们在运行的时候还可以动态地去操作他们. 理论的东东太多也没用,下面我们看看实践 Demo - Demo: package cn.lee.demo; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import

Java反射学习总结

广州疯狂软件教育Java培训,iOS培训分享Class类是Reflection API中核心的类,他位于java.lang.Class列出一些常用的方法.- getName() : 获得类的完整名字- getFields() : 获得类的public类型的属性- getDeclaredFields() : 获得类的所有属性- getMethods() : 获得类的public类型的方法- getDeclaredMethods() : 获得类的所有方法- getMethod(String name

大型网站系统与Java中间件实践

大型网站系统与Java中间件实践(贯通分布式高并发高数据高访问量网站架构与实现之权威著作,九大一线互联网公司CTO联合推荐) 曾宪杰 著   ISBN 978-7-121-22761-5 2014年4月出版 定价:65.00元 340页 16开 编辑推荐 到底是本什么书,拥有这样一份作序推荐人列表:阿里集团章文嵩博士|新浪TimYang|去哪网吴永强|丁香园冯大辉|蘑菇街岳旭强|途牛汤峥嵘|豆瓣洪强宁|淘宝陈皓/林昊-- 这本书出自淘宝技术部总监之手,他也是淘宝近10年来历次技术飞跃的参与者.贡

java 反射(reflect)总结,附对象打印工具类

java反射机制认知 java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取类的信息以及动态调用对象的方法的功能称为java语言的反射机制Reflection. 这就说明:Java程序可以加载一个编译期间完全未知的class,获悉其完整构造,并生成其对象实体.或对其fields设值.或唤起其methods.虽然java并不是动态语言. 如何达到上述目的,是本文探讨的内容.本文将介绍Reflection A

Java反射实现原理分析

一.反射的用法 1.如何获取Class反射类 (1)通过getClass方法: Proxy proxy = new ProxyImpl(); Class proxyClazz = proxy.getClass(); (2)通过Class.forName方法 Proxy proxy = new ProxyImpl(); Class proxyClazz = Class.forName("com.dh.yjt.SpringBootDemo.test.Reflect.Proxy"); (3)

一文带你了解Java反射机制

想要获取更多文章可以访问我的博客?-?代码无止境. 上周上班的时候解决一个需求,需要将一批数据导出到Excel.本来公司的中间件组已经封装好了使用POI生成Excel的工具方法,但是无奈产品的需求里面有个合并单元格的要求,工具类中找了半天也没发现适用的方法,就只能自己撸起袖子干了.导出Excel的工具方法会少不了使用反射,但是反射这东西对于我这种写业务代码的人来说接触比较少,所以就恶补了一下,写下这篇文章记录一下. 什么是反射 万物究其根,研究一样新东西,首先我们需要了解它是什么,干什么用的.在