Java 反射 思考

所谓反射,是指在运行时状态中,获取类中的属性和方法,以及调用其中的方法的一种机制。这种机制的作用在于获取运行时才知道的类(Class)及其中的属性(Field)、方法(Method)以及调用其中的方法,也可以设置其中的属性值。

在Java中实现反射最重要的一步,也是第一步就是获取Class对象,得到Class对象后可以通过该对象调用相应的方法来获取该类中的属性、方法以及调用该类中的方法。

Java中反射有如下几种实现方式:

1、通过Class.forName()方法加载字符串,就可以得到该字符串做代表的Class对象。

例如:Class<?> clazz = Class.forName("java.lang.String")就可以得到String类的Class对象。值得注意的是,字符串必须是类的全名,即包名+类名。

下边的代码是Struts配置文件struts.xml中的一个action的配置。

<action name="registe" class="cn.com.huixin.struts2.RegisteAction">
   <result>/registeResult.jsp</result>
   <result name="input">/registe2.jsp</result>
</action>

这里的class属性给出了一个类的全名的字符串,服务器是如何通过这个字符串得到类对象的呢?就是通过反射机制RegisteAction对象的。然后再去调用这个类中的默认的execute()方法。

2、通过类名调用class属性得到该类的Class对象。

例如:Class<?> clazz = String.class也可以得到String类的Class对象。

3、调用实例的getClass()方法。

例如:Date date = new Date();

Class<?> clazz = date.getClass();

通过上边的两句代码就可以得到date实例的Class对象。

1 获取 反射的对象

package com.qianfeng.reflect;

import com.qianfeng.domain.Person;

/*
反射:动态获取类或类中成员,并使用类或类中成员
获取一个类字节码文件对象的方式 (类名的.class)
*/
public class ReflectDemo1 {

	public ReflectDemo1() {
		// TODO Auto-generated constructor stub
	}
	public static void main(String[] args) throws ClassNotFoundException {

				//get1();
				//get2();
		          get3();

	}
	private static void get3() throws ClassNotFoundException {
		//通过字符串形式的名称来获取字节码文件对象,不需要对象,也不需要类
		Class claz = Class.forName("com.qianfeng.domain.Person");
		System.out.println(claz);

	}
	private static void get2() {
		//每个数据类型都有一个class属性,可以通过类的该属性获取其所属类的字节码文件对象
		//不需要对象,但是需要类
		Class claz = Person.class;
		Class claz2 = Person.class;

		System.out.println(claz==claz2);

	}
	private static void get1() {
		//方式一:通过对象来获取所属类的字节码文件对象
		//任何一个对象都有其所属类的字节码文件对象
		//new Person()  Person.class
		//特点:这种方式需要创建对象

		Person p1 = new Person();

		Class claz1 = p1.getClass();//Person.class

		Person p2 = new Person();

		Class claz2 = p2.getClass();//Person.class

		System.out.println(claz1==claz2);

	}

}

2  获取反射的对象的构造方法

package com.qianfeng.reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

import com.qianfeng.domain.Person;

public class ReflectDemo2 {

	/**
	 * @param args
	 * @throws ClassNotFoundException
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 * @throws SecurityException
	 * @throws NoSuchMethodException
	 * @throws InvocationTargetException
	 * @throws IllegalArgumentException
	 */
	public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
		//动态获取类,并创建对象

		createObj();

		createObj2();
	}

	private static void createObj2() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		//动态获取类
		String str="com.qianfeng.domain.Person";
		Class claz = Class.forName(str);
		//int.class;
		//使用带参数的构造方法创建对象
		//首先要得到带参数的构造方法
		//Person p = new Person("lsdjkf",34);//String.class int.class

		Constructor con = claz.getConstructor(String.class,int.class);

		//使用获取到的构造方法创建对象

		Object obj = con.newInstance("李四",29);//调用构造方法对象的newInstance()方法

		System.out.println(obj);

	}

	private static void createObj() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
		//Person p = new Person();
		//1加载Person.class  2:开辟内存  3:构造方法

		//动态获取类
		String str="com.qianfeng.domain.Person";
		Class claz = Class.forName(str);

		//创建对象
		Object obj = claz.newInstance();//调用这个字节码文件对象的newInstance()方法

		System.out.println(obj);

	}

}

3 获取对象中的成员变量

package com.qianfeng.reflect;

import java.lang.reflect.Field;

public class ReflectDemo3 {

	/**
	 * @param args
	 * @throws ClassNotFoundException
	 * @throws SecurityException
	 * @throws NoSuchFieldException
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 */
	public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException {
		// 动态获取类并创建对象后,访问成员属性

		accessField();

	}

	private static void accessField() throws ClassNotFoundException, NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException {
		//Person p = new Person();
		//p.name = "";
		//动态获取类
		String str="com.qianfeng.domain.Person";
		Class claz = Class.forName(str);

		//获取字段
		//Field f = claz.getField("name");//只能获取权限是public的字段
		Field f = claz.getDeclaredField("name");
		//System.out.println(f);

		//给字段赋值--需要先有对象
		//创建对象
		Object obj = claz.newInstance();

		//设置权限为可访问的

		f.setAccessible(true);//暴力访问

		//给字段赋值

		f.set(obj, "小花");

		System.out.println(obj);

	}

}

4 获取对象中的方法

package com.qianfeng.reflect;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflectDemo4 {

	/**
	 * @param args
	 * @throws ClassNotFoundException
	 * @throws SecurityException
	 * @throws NoSuchMethodException
	 * @throws InvocationTargetException
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 */
	public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		//动态获取类并创建对象后,访问成员方法

	//	accessMethod();
		accessMethod1();
		accessMethod2();

	}

	private static void accessMethod2() throws NoSuchMethodException, SecurityException, ClassNotFoundException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
	 	//动态获取类
    	String str="com.qianfeng.domain.Person";
    	Class claz = Class.forName(str);

    	Method m = claz.getMethod("meth", null);

    	m.invoke(null,null);

	}

	//得到带参数的方法并执行
    private static void accessMethod1() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
    	//动态获取类
    	String str="com.qianfeng.domain.Person";
    	Class claz = Class.forName(str);

    	Method  m = claz.getMethod("func", String.class);

    	Object obj = claz.newInstance();

    	m.invoke(obj, "haha");

	}
	//得到不带参数的方法并执行
	private static void accessMethod() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		//动态获取类
		String str="com.qianfeng.domain.Person";
		Class claz = Class.forName(str);

		Method m = claz.getMethod("show",null);

		//创建对象
		Object obj = claz.newInstance();

		m.invoke(obj,null);

	}

}

时间: 2024-10-09 07:28:07

Java 反射 思考的相关文章

java反射的应用实践

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

java反射field和method的顺序问题

最近在有思考到序列化性能优化的问题,关于java反射field和method的顺序问题,这里有详细的讨论http://stackoverflow.com/questions/5001172/java-reflection-getting-fields-and-methods-in-declaration-order javadoc不保证顺序,所以最好的方式仍然是通过自定义注解处理器实现,比如典型的可以借用jackson 的ordered注解JsonPropertyOrder或者objectMap

Java 反射机制(包括组成、结构、示例说明等内容)

http://www.cnblogs.com/skywang12345/p/3345205.html 第1部分 Java 反射机制介绍 Java 反射机制.通俗来讲呢,就是在运行状态中,我们可以根据"类的部分已经的信息"来还原"类的全部的信息".这里"类的部分已经的信息",可以是"类名"或"类的对象"等信息."类的全部信息"就是指"类的属性,方法,继承关系和Annotation

【java】java反射初探 ——“当类也照起镜子”

反射的作用 开门见山地说说反射的作用 1.为我们提供了全面的分析类信息的能力 2.动态加载类 我理解的“反射”的意义 (仅个人理解哈) 我理解的java反射机制就是: 提供一套完善而强大的API“反射“类的结构. 打个比方,反射机制就像是一面镜子,而类就像是一个在照着镜子的人. 镜子(反射机制)照出(反射)了人的全貌(类的全方位的信息,例如方法,成员变量和构造器等的相关信息) 为什么要照镜子? 因为不照镜子看不清楚自己的全貌,“镜子”就是为了解决这个问题出现的(为我们提供全面分析类的能力) 好吧

Java反射初探 ——“当类也学会照镜子”

反射的作用 开门见山地说说反射的作用 1.为我们提供了全面的分析类信息的能力 2.动态加载类 我理解的“反射”的意义 (仅个人理解哈) 我理解的java反射机制就是: 提供一套完善而强大的API“反射“类的结构. 打个比方,反射机制就像是一面镜子,而类就像是一个在照着镜子的人. 镜子(反射机制)照出(反射)了人的全貌(类的全方位的信息,例如方法,成员变量和构造器等的相关信息) 为什么要照镜子? 因为不照镜子看不清楚自己的全貌,“镜子”就是为了解决这个问题出现的(为我们提供全面分析类的能力) 好吧

Java 反射机制介绍

参考文章:http://www.cnblogs.com/skywang12345/p/3345205.html Java 反射机制.通俗来讲呢,就是在运行状态中,我们可以根据"类的部分已经的信息"来还原"类的全部的信息".这里"类的部分已经的信息",可以是"类名"或"类的对象"等信息."类的全部信息"就是指"类的属性,方法,继承关系和Annotation注解"等内容.

Java反射

1. 介绍 反射是一种能够在程序运行时动态访问.修改某个类中任意属性和方法的机制. 具体:对于任意一个类,都能够知道这个类的所有属性和方法对于任意一个对象,都能够调用它的任意一个方法和属性 在运行时,当加载完类之后,JVM在堆内存中会自动产生一个Class类型的对象,这个对象包含了完整的类的结构信息 这个Class对象就像一面镜子,透过这个镜子看到类的结构 那么,如何得到这个Class对象呢?以下可否 Class c = new Class(); 答案是不行的,因为Class的构造函数定义为私有

Java 反射详解

反射反射,程序员的快乐,今天你快乐了吗?如果你不快乐,没关系,接下来让你快乐起来! 一.什么是反射? 通过百度百科我们可以知道,Java反射就是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:并且能改变它的属性.而这也是Java被视为动态(或准动态,为啥要说是准动态,因为一般而言的动态语言定义是程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言.从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C

java反射机制(一)—— 利用反射机制实例化对象

一.Java有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时加载.探知.使用编译期间完全未知的classes.换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体.或对其fields设值.或唤起其methods.(度娘文库是这么说的) 二.这篇文章主要介绍一下通过反射机制去实例化一个类的对象,然后调用其方法.本文主要介绍两种方式,第一种就是通过构造函数来实例化,第二种就是通过Cl