`
破晓之刃
  • 浏览: 6033 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类

java反射类应用分析

 
阅读更多

 

一、什么是反射:

        在计算机科学领域,反射是指一类应用,它们能够自描述和自控制。也就是说,这类应用通过采用某种机制来实现对自己行为的描述(self-representation)和监测(examination),并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。

 二、反射机制的功能:

      1.在运行时判断任意一个对象所属的类

      2.在运行时构造任意一个类的对象

      3.在运行时判断任意一个类所具有的成员变量和方法(通过反射甚至可以调用private方法)

      4.在运行时调用任意一个对象的方法(*****注意:前提都是在运行时,而不是在编译时)

 

       Java 反射相关的API简介:(位于java。lang。reflect包中)

        --Class类:代表一个类

        --Filed类:代表类的成员变量

        --Method类:代表类的方法

        --Constructor类:代表类的构造方法

        --Array类:提供了动态创建数组,以及访问数组的元素的静态方法。该类中的所有方法都是静态方法

       Reflection 是 Java 被视为动态(或准动态)语言的关键它允许运行中的 Java 程序对自身进行检查,或者说“自审”,并能直接操作程序的内部属性和方法

    

三、什么情况下用到反射:

 

    1. 比如此方法是private的,你不能直接调用,反射可以; 

    2. 比如你只知道此方法名的规则,运行时才知道具体方法,你无法直接调用。 

    例如setter方法,框架在运行时才知道某类有“name”属性,根据setter规则构造方法名“setName”,这时只能通过反射来调用; 

    就像我们的编程之中有动态和静态之分,反射的作用就是动态的获取一个类的属性和方法。例如我们定义了一个接口,实现这个接口的类有20个,程序里用到了这个实现类的地方有好多地方,如果我们不使用配置文件手写的话,代码的改动量是不是很大呢,因为每个地方都要改而且不容易定位,如果我们在编写之前先将接口与实现类的写在配置文件里,下次只需改配置文件,利用反射(java API已经封装好了,你直接用就可以用 Class.newInstance())就可完成。

 

      因为学习的还比较浅显,什么情况的反射没有找到很好的解释,上面也是我看到和想到的一些情况,欢迎补充。

  

 

下面是关于反射类测试的一些java代码:

这个类是用来测试的,它继承了Object类,有一个接口是ActionListener,两个属性int和Integer,两个构造方法和两个方法。

 

public class A extends Object implements ActionListener{
    private int a=3;
    public Integer b=new Integer(4);
    public A(){}
    public A(int id ,String name){}
    public int abc(int id,String name){return 0;}
	
	public void actionPerformed(ActionEvent e) {
		
	}	
}

 那么我们要拿A类做什么呢?我们把A类作为一个反射类,利用反射类的方法去取A中的属性和方法。

 

 

public class B {
	public static void main(String args[]) {
		A r = new A();
		Class temp = r.getClass();

		System.out.println("反射类中所有公有属性");
		Field[] fb = temp.getFields();
		for (int j = 0; j < fb.length; j++) {
			Class c1 = fb[j].getType();
			System.out.println("属性:" + c1);
		}

		System.out.println("反射类中的所有属性");
		Field[] fa = temp.getDeclaredFields();
		for (int j = 0; j < fa.length; j++) {
			Class c1 = fa[j].getType();
			System.out.println("fa:" + c1);
		}

		System.out.println("反射类中私有属性的值");
		try {
			Field f = temp.getDeclaredField("a");
			f.setAccessible(true);
			Integer i = (Integer) f.get(r);
			System.out.println(i);
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}

	}
}

      这里用到了两个方法,getFields()、getDeclaredFields(),它们分别是用来获取反射类中所有公有属性和反射类中所有的属性的方法。另外还有getField(String)和getDeclaredField(String)方法都是用来过去反射类中指定的属性的方法,要注意的是getField方法只能取到反射类中公有的属性,而getDeclaredField方法都能取到私有属性。 这里还用到了Field 类的setAccessible方法,它是用来设置是否有权限访问反射类中的私有属性的,只有设置为true时才可以访问,默认为false。另外 Field类还有set(Object AttributeName,Object value)方法,可以改变指定属性的值。

 

 

下面的代码是如何获取反射类的构造方法和方法:

 

public class C {
	public static void main(String[] args){
		A r=new A();
		printConstructors(r);
	}
	
	public static void printConstructors(A r){
		Class c=r.getClass();
		//获取指定的类名
		String className=c.getName();
		//获取指定构造器
		Constructor[] theConstructors=c.getConstructors();
		for(int i=0;i<theConstructors.length;i++){
			//获取指定构造方法的参数的集合
			Class[] parameterTypes=theConstructors[i].getParameterTypes();
		    
		 	System.out.print(className+"(");
		 	for(int j=0;j<parameterTypes.length;j++){
		 		System.out.print(parameterTypes[j].getName()+" ");	
		 	}
		 	System.out.println(")");
		 	
		}
	}

}

 

public class D {
	public static void main(String[] args){
		A p=new A();
		printMethods(p);
	}
	
	public static void printMethods(Object o){
		Class c=o.getClass();
		String className=c.getName();
		Method[] m=c.getMethods();
		for(int i=0;i<m.length;i++){
			//输出方法返回类型
			System.out.print(m[i].getReturnType().getName());
			//输出方法名
			System.out.print(" "+m[i].getName()+"(");
			//获取方法的参数
			Class[] parameterTypes=m[i].getParameterTypes();
			for(int j=0;j<parameterTypes.length;j++){
				System.out.print(parameterTypes[j].getName());
				if(parameterTypes.length>j+1){
					System.out.print(",");
				}
			}
			System.out.println(")");
		}
		
	}

}

 

 

 

既然我们能获取反射类的属性、构造方法、父类、接口和方法,可这些东西能帮我们做些什么呢?我们可以利用反射类生成实体对象。

      想生成对象的实体,在反射动态机制中有两种方法,一个针对无变量的构造方法,一个针对带参数的构造方法,,如果想调用无参数的构造函数直接调用Class类中的newInstance(),而如果想调用有参数的构造函数,则需要调用Constructor类中newInstance()方法,首先准备一个Class[]作为Constructor的参数类型。然后调用该Class对象的getConstructor()方法获得一个专属的Constructor的对象,最后再准备一个Object[]作为Constructor对象昂的newInstance()方法的实参。 在这里需要说明的是 只有两个类拥有newInstance()方法,分别是Class类和Constructor类,Class类中的newInstance()方法是不带参数的,而Constructro类中的newInstance()方法是带参数的需要提供必要的参数。

 

	public static void main(String[] args) throws InstantiationException,
			IllegalAccessException, IllegalArgumentException,
			SecurityException, InvocationTargetException, NoSuchMethodException {

		Customer2 customer = new Customer2();

		Class cls = customer.getClass();

		// 获得Class所代表的对象的所有类型的构造函数Constructor的数组
		Constructor ctor[] = cls.getDeclaredConstructors();

		for (int i = 0; i < ctor.length; i++) {

			// 获得对应的构造函数参数列表的Class类型的数组
			Class cx[] = ctor[i].getParameterTypes();

			if (cx.length == 0) {
				// 无参的构造函数可以通过Class实例直接调用Class类的newInstance()方法
				Object obj = cls.newInstance();
				// 同样也可以象以下这样构造,调用Constructor类的newInstance()方法
				// Customer2
				// obj=(Customer2)cls.getConstructor(cx).newInstance(new
				// Object[]{});
				System.out.println(obj);
			} else if (cx.length == 2) {
				// 此时只能调用Constructor类的newInstance()方法,注意:利用反射调用的是私有private的构造方法
				Customer2 obj = (Customer2) cls.getConstructor(cx).newInstance(
						new Object[] { new Long(123), "MWJ" });
				System.out.println(obj);
			} else if (cx.length == 3) {
				// 此时只能调用Constructor类的newInstance()方法,注意:利用反射调用的是公有public的构造方法
				Customer2 obj = (Customer2) cls.getConstructor(cx).newInstance(
						new Object[] { new Long(133), "MWJ", new Integer(20) });
				System.out.println(obj);
			}
		}

	}
}

class Customer2 {

	private Long id;

	private String name;

	private int age;

	/**
	 * 无参数的构造函数
	 * 
	 */
	public Customer2() {

	}
	/**
	 * public修饰的有参数的构造函数,3个参数
	 * 
	 * @param id
	 * @param name
	 * @param age
	 */
	public Customer2(Long id, String name, int age) {
		this.id = id;
		this.name = name;
		this.age = age;
	}

	/**
	 * public修饰的构造函数,2个参数
	 * 
	 * @param id
	 * @param name
	 */
	public Customer2(Long id, String name) {
		this.id = id;
		this.name = name;
		this.age = age;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String toString() {
		return ("id==" + this.getId() + "  Name==" + this.getName() + " Age:" + this
				.getAge());
	}

}

 程序执行结果如下:

id==123  Name==MWJ Age:0

id==133  Name==MWJ Age:20

id==null  Name==null Age:0

 

 

 

 

分享到:
评论

相关推荐

    Java反射性能测试分析

    ### Java反射性能测试分析 #### 引言 Java反射机制是Java编程语言中一个强大的特性,它允许程序在运行时动态地访问、检测和修改类、接口、字段和方法等对象。然而,反射操作通常会引入额外的开销,这在性能敏感的...

    java反射机制应用

    Java反射机制是Java语言提供的一种能在运行时分析类信息并动态操作对象的功能。通过反射,我们可以在程序运行期间获取类的信息(如类名、方法名等),创建对象,调用方法等。这为Java程序带来了极大的灵活性和扩展性...

    java反射 java反射 java反射java反射

    Java反射是Java编程语言中的一个重要特性,它允许程序在运行时动态地获取类的信息并操作类的对象。在Java中,反射机制提供了强大的能力,包括在运行时检查类的结构、创建对象实例、调用方法以及访问和修改字段值。...

    Java反射机制经典案例

    Java反射机制是Java编程语言中的一个强大特性,它允许程序在运行时检查并操作类、接口、字段和方法等对象。这种能力使得Java代码能够具备动态性,可以在不知道具体类名的情况下实例化对象,调用方法,访问字段,以及...

    java 利用反射获取内部类静态成员变量的值操作.docx

    ### Java 利用反射获取内部类静态成员变量的值操作 #### 一、引言 在Java编程中,反射是一个非常强大的工具,它允许程序在运行时检查类、接口、字段和方法...希望本文能帮助大家更好地理解和掌握Java反射技术的应用。

    Java反射机制总结(实例分析)

    Java反射机制是Java编程语言中的一个重要特性,它允许程序在运行时动态地获取类的信息并进行操作。通过反射,开发者可以在程序执行时发现并访问类的字段(fields)、方法(methods)以及构造器(constructors),...

    java反射源代码

    Java反射是Java编程语言中的一个强大特性,它允许在运行时检查类、接口、字段和方法的信息,并且能够在运行时动态地创建对象和调用方法。这个特性使得Java具有高度的灵活性,尤其在处理框架、插件系统以及元数据驱动...

    Java反射机制Demo

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

    JAVA反射详细讲解

    总结,Java反射是Java语言的一个强大特性,它提供了运行时分析和操作类的能力,极大地拓展了Java的灵活性。然而,使用反射也需要谨慎,合理运用才能发挥其优势,避免潜在的问题。理解并熟练掌握反射,对于提升Java...

    java例子 java反射

    Java反射是Java编程语言中的一个强大特性,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。...通过分析这些例子,你可以更深入地理解Java反射的使用方式及其在实际开发中的应用。

    java反射经典实例

    - 反射机制是在运行时分析类的能力,它允许我们获取类的信息(如类名、方法、属性等),甚至能够在运行时动态创建对象并调用其方法。 - 主要用途包括:动态加载类、处理未知类型的对象、实现元编程、插件系统、...

    Java 反射-动态代理

    Java反射允许我们在运行时检查类、接口、字段和方法的信息,甚至可以创建和调用对象。它主要通过java.lang.Class类和java.lang.reflect包中的类(如Constructor、Method和Field)来实现。以下是一些核心知识点: 1....

    Java反射函数机制实现List转换Json

    在Java中,反射主要用于在运行时分析类和对象,包括获取类的信息、创建对象、调用方法以及访问和修改字段值。这种能力在处理动态类型、元编程以及框架和库的设计中尤其有用。本话题将深入探讨如何利用Java反射机制将...

    候捷谈Java反射机制

    Java反射机制是Java编程语言中的一个重要特性,它允许程序在运行时获取和操作任何已知名称的类的内部信息。这一机制使得Java具备了一定的动态性,虽然在传统的分类中Java被视为静态类型语言。通过反射,开发者可以在...

    java反射机制

    6. **JAVA反射原理分析** Java反射机制基于`Class`文件结构和JVM的类加载机制。`Class`文件包含了类的元数据,而JVM在加载类时会解析这些元数据,并通过反射API提供访问。 7. **JAVA反射的应用** 反射在许多场景...

    java反射实例

    Java反射是Java编程语言中的一个强大特性,它允许在运行时检查类、接口、字段和方法的信息,并且能够在运行时动态地创建对象和调用...在分析Java反射源码时,可以更深入地了解其内部实现机制,提升对Java平台的理解。

    Java Reflection (JAVA反射)详解

    Java 反射(Reflection)是Java编程语言的一个重要特性,它允许程序在运行时动态地获取类的信息(如类名、方法、字段等)并直接操作对象的内部属性。这为开发者提供了强大的灵活性,能够在不预先知道具体类的情况下...

    java反射性能测试分析.pdf

    《Java反射性能测试分析》 Java反射机制是Java语言中的一个重要特性,它允许程序在运行时动态地获取类的信息并调用其方法,极大地增强了代码的灵活性和可扩展性。然而,反射在带来便利的同时,也因其相对较低的性能...

    Java反射机制

    9. **分析Java反射Class类型的源代码**:深入理解反射机制的工作原理,了解Class文件的结构以及JVM如何加载类对象以支持反射操作。 #### 四、Java反射原理分析 1. **Class文件结构**:每个编译后的Java类都会生成...

    Java反射机制的使用和学习方法

    Java反射机制是Java编程语言中的一个强大特性,它允许程序在运行时检查和操作类、接口、对象等的内部信息。这一机制对于理解和实现高级框架、动态代理、元数据处理等场景至关重要。以下是对Java反射机制的详细说明:...

Global site tag (gtag.js) - Google Analytics