`

java 反射

    博客分类:
  • java
 
阅读更多
Class<T>类(在java.lang包中,Instances of the class Classrepresent classes and interfaces in a running Javaapplication):在Java中,每个class都有一个相应的Class对象。也就是说,当我们编写一个类,编译完成后,在生成的.class文件中,就会产生一个Class对象,用于表示这个类的类型信息。
T - 由此 Class 对象建模的类的类型。例如,String.class 的类型是Class<String>。如果将被建模的类未知,则使用 Class<?>。
User类
package com.test.reflect;

/**
 * @author cxl
 * 2013-10-26
 */
public class User {
	
	private String name;
	private int age;
	
	public User() {
		
	}
	
	public User(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public String getName() {
		System.out.println("getter name is " + this.name);
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
		System.out.println("setter name is " + name);
	}
	
	public int getAge() {
		return age;
	}
	
	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return "User [age=" + age + ", name=" + name + "]";
	}
	
	public String getCountryInfo(String country) {
		return "I come from " + country;
	}
	
	private String sayHello(String name) {
		return "hello," + name;
	}
}
获取Class类的对象
一、通过getClass()方法获取
利用对象调用getClass()方法获取该对象的Class实例;
二、通过forName()方法获取
使用Class类的静态方法forName(),用类的名字获取一个Class实例
三、通过类.class方式获取
使用类.class方式Class实例,对于基本数据类型的封装类,还可以采用.TYPE来获取相对应的基本数据类型的Class实例
DemoClass类
import com.test.reflect.User;


public class DemoClass {
	public static void main(String[] args) throws Exception {
		User u = new User();
		// 1.通过getClass()方法获取
		Class<?> userClass1 = u.getClass();
		System.out.println(userClass1.getName());//com.test.reflect.User
		// 2.通过forName()方法获取
		Class<?> userClass2 = Class.forName("com.test.reflect.User");
		System.out.println(userClass2.getName());//com.test.reflect.User
		// 3.通过类.class方式获取
		Class<?> userClass3 = User.class;
		System.out.println(userClass3.getName());//com.test.reflect.User
		// 基础类型.class方式
		Class<?> userClass4 = int.class;
		System.out.println(userClass4.getName());//int
		// 基础类型包装类.TYPE获取
		Class<?> userClass5 = Integer.TYPE;
		System.out.println(userClass5.getName());//int
		// 基础类型包装类.class
		Class<?> userClass6 = Integer.class;
		System.out.println(userClass6.getName());//java.lang.Integer
	}
}
 获取相应类的实例化对象
DemoInstance类
import java.lang.reflect.Constructor;

import com.test.reflect.User;

public class DemoInstance {
	public static void main(String[] args) throws Exception {
		Class<?> userClass = Class.forName("com.test.reflect.User");
		//获取所有构造方法
		Constructor<?>[] constructors = userClass.getConstructors();
		for (Constructor<?> constructor : constructors) {
			System.out.println(constructor);
			//public com.test.reflect.User(java.lang.String,int)
			//public com.test.reflect.User()
		}
		//一、根据指定的构造方法实例化对象
		//1.通过无参的构造方法实例化对象
		User user = (User)userClass.newInstance();
		user.setName("hello");//setter name is hello
		user.setAge(25);
		user.getName();//getter name is hello
		System.out.println(user);//User [age=25, name=hello]
		
		//2.通过有参的构造方法实例化对象
		Constructor<?> constructor = userClass.getConstructor(String.class,int.class);
		//Constructor<?> constructor = userClass.getConstructor(new Class[]{String.class,int.class});
		User u = (User)constructor.newInstance("world",27);
		//User u = (User)constructor.newInstance(new Object[]{"world",27});
		System.out.println(u);//User [age=27, name=world]
		
		//二、根据构造方法的数组实例化对象(注意得到构造方法的顺序)
		User u1 = (User)constructors[0].newInstance("cxl",25);
		System.out.println(u1);//User [age=25, name=cxl]
		User u2 = (User)constructors[1].newInstance();
		System.out.println(u2);//User [age=0, name=null]
	}
}
 获取class对象中的方法
import java.lang.reflect.Method;

public class DemoMethod {
	public static void main(String[] args) throws Exception {
		Class<?> userClass = Class.forName("com.test.reflect.User");
		//1.getMethods()获取类public的方法(包括继承的方法)
		Method[] methods1 = userClass.getMethods();
		System.out.println("getMethods()获取的方法有:");
		for (Method method : methods1) {
			System.out.println(method);
		}
		//2.getDeclaredMethods()获取类的所有方法(但不包含继承的方法)
		System.out.println("getDeclaredMethods()获取的方法有:");
		Method[] methods2 = userClass.getDeclaredMethods();
		for(Method method : methods2){
			System.out.println(method);
		}
	}
}
 打印结果:
getMethods()获取的方法有:
public int com.test.reflect.User.getAge()
public void com.test.reflect.User.setAge(int)
public int com.test.reflect.User.add(int,int)
public java.lang.String com.test.reflect.User.toString()
public java.lang.String com.test.reflect.User.getName()
public void com.test.reflect.User.setName(java.lang.String)
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 native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public boolean java.lang.Object.equals(java.lang.Object)
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
getDeclaredMethods()获取的方法有:
public int com.test.reflect.User.getAge()
public void com.test.reflect.User.setAge(int)
public int com.test.reflect.User.add(int,int)
public java.lang.String com.test.reflect.User.toString()
public java.lang.String com.test.reflect.User.getName()
public void com.test.reflect.User.setName(java.lang.String)
 获取class对象中的属性 
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class DemoField {
	public static void main(String[] args) throws Exception {
		Class<?> userClass = Class.forName("com.test.reflect.User");
		Field[] fields = userClass.getDeclaredFields();
		for (Field field : fields) {
			//获取属性
			System.out.println("属性 :" + field.getName());
			int mod = field.getModifiers();
			//获取属性修饰符
			System.out.println("属性修饰符 :" + Modifier.toString(mod));
			//获取属性类型
			System.out.println("属性类型:" + field.getType().getName());
			System.out.println(Modifier.toString(mod) + " " + 
					field.getType().getName() + " " + field.getName());
		}
	}
}
 打印结果:
属性 :name
属性修饰符 :private
属性类型:java.lang.String
private java.lang.String name
属性 :age
属性修饰符 :private
属性类型:int
private int age
 通过getFields()方法可以获取父类或者接口的public属性,getDeclaredFields()获得某个类的所有申明的属性,类似的方法有getConstructors()和getDeclaredConstructors(),getMethods()和getDeclaredMethods()。
通过getInterfaces()方法获取实现的接口,通过getSuperclass()方法获取继承类
通过反射调用方法
DemoInvoke类
import java.lang.reflect.Field;
import java.lang.reflect.Method;

import com.test.reflect.User;

/**
 * 反射调用方法
 */
public class DemoInvoke {

	public static void main(String[] args) throws Exception {
		Class<?> userClass = Class.forName("com.test.reflect.User");
		User user = (User) userClass.newInstance();
		/**
		 * 通过反射调用User类的普通方法 getMethod(String name, Class<?>... parameterTypes)
		 * name指调用的方法名 ,parameterTypes是指按声明顺序标识该方法入参类型的 Class对象的一个数组 可以通过
		 * new Class数组完成,如new Calss[]{String.class}{}中是入参类型的Class对象
		 */
		Method method = userClass.getMethod("getCountryInfo", String.class);
		String countryInfo = (String)method.invoke(user, "China");
		System.out.println(countryInfo);//I come from China
		
		/**
		 * 调用反射User类的setter,getter方法
		 */
		Field[] fields = userClass.getDeclaredFields();
		for (Field field : fields) {
			//属性
			String fieldName = field.getName();
			//setter方法名
			String setterName = "set" + fieldName.substring(0, 1).toUpperCase()
					+ fieldName.substring(1);
			//getter方法名
			String getterName = "get" + fieldName.substring(0, 1).toUpperCase()
					+ fieldName.substring(1);
			//获取setter方法
			Method setterMethod = userClass.getMethod(setterName,
					new Class[] {field.getType()});
			//获取getter方法
			Method getterMethod = userClass.getMethod(getterName,
					new Class[] {});
			System.out.println(field.getType().getSimpleName());//String int
			//setter方法
			if(field.getType().getName().equals("java.lang.String")) {
				setterMethod.invoke(user, "test");//setter name is test
			}
			if(field.getType().getName().equals("int")) {
				setterMethod.invoke(user, 25);
			}
			Object fieldValue = getterMethod.invoke(user);//getter name is test
			System.out.println("field : " + fieldName + " = " + fieldValue);
		}
		System.out.println(user);//User [age=25, name=test]
		
		DemoInvoke demoInvoke = new DemoInvoke();
		user = new User("lucy",18);
		User userCopy = (User)demoInvoke.copy(user);
		System.out.println(userCopy);//User [age=18, name=lucy]
	}
	
	/**
	 * 实现对User对象的拷贝
	 * @param obj
	 * @return
	 * @throws Exception
	 */
	public Object copy(Object obj) throws Exception {
		
		//获取obj的Class对象
		Class<?> objClass = obj.getClass();
		
		//通过相应的Class对象的newInstance()new一个要返回的对象
		Object objCopy = objClass.newInstance();
		
		/*等价于Object objCopy = objClass.getConstructor(new Class[] {})
				.newInstance(new Object[] {});*/

		Field[] fields = objClass.getDeclaredFields();
		for (Field field : fields) {
			//属性
			String fieldName = field.getName();
			//setter方法名
			String setterName = "set" + fieldName.substring(0, 1).toUpperCase()
					+ fieldName.substring(1);
			//getter方法名
			String getterName = "get" + fieldName.substring(0, 1).toUpperCase()
					+ fieldName.substring(1);
			//获取setter方法
			Method setterMethod = objClass.getMethod(setterName,
					new Class[] { field.getType() });
			//获取getter方法
			Method getterMethod = objClass.getMethod(getterName,
					new Class[] {});
			//调用getter方法,得到传入的obj对象的属性值
			Object fieldValue = getterMethod.invoke(obj);
			//调用setter方法,设置objCopy对象的属性值为obj对象的属性值
			setterMethod.invoke(objCopy, new Object[]{fieldValue});
		}
		return objCopy;
	}
}
 访问私有成员变量及方法
DemoPrivate类
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import com.test.reflect.User;

public class DemoPrivate {
	public static void main(String[] args) throws Exception {
		Class<?> userClass = Class.forName("com.test.reflect.User");
		User user = (User) userClass.newInstance();
		
		//访问私有方法,注:通过getDeclaredMethod()方法获取method对象,不能通过getMethod()方法
		Method method = userClass.getDeclaredMethod("sayHello", String.class);
		//压制Java对访问修饰符的检查
		method.setAccessible(true);
		String sayInfo  = (String)method.invoke(user, "world");//hello,world
		System.out.println(sayInfo);

		//操作私有属性,注:通过getDeclaredField()方法获取method对象
		Field field = userClass.getDeclaredField("name");
		//压制Java对访问修饰符的检查
		field.setAccessible(true);
		field.set(user, "lily");
		System.out.println(field.get(user));//lily
	}
}
 
 
 
 
分享到:
评论

相关推荐

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

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

    JAVA反射机制的入门代码

    Java反射机制是Java编程语言中的一个强大特性,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。这个特性使得Java具有了高度的灵活性和动态性,尤其是在处理元数据、创建对象、调用私有方法...

    java反射,获取所有属性、方法以及List集合类

    Java反射是Java编程语言中的一个强大工具,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。在Java中,反射主要用于在运行时分析类和对象,包括访问私有成员、调用私有方法、创建对象、获取类...

    JAVA 反射机制应用

    Java反射机制是Java语言提供的一种强大功能,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。在Java中,反射机制的核心类是java.lang.Class,它代表了运行时的类信息。通过Class对象,我们...

    java 反射得到某个方法

    在本文中,我们将深入探讨如何使用Java反射来获取并执行某个特定的方法。 首先,我们需要了解Java反射的基本概念。`java.lang.Class`类是反射的核心,它代表了Java中的每一个类。我们可以通过以下方式获取到一个...

    Java反射性能测试分析

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

    Java反射机制总结

    ### Java反射机制总结 #### 反射的概念与起源 反射的概念最早由Smith于1982年提出,指的是程序能够访问、检测并修改其自身状态或行为的能力。这一概念的提出迅速引起了计算机科学领域的广泛关注,并在之后的研究中...

    Java反射经典实例

    Java反射是Java编程语言中的一个强大特性,它允许运行时的程序访问并操作类、接口、字段和方法等信息,即使这些信息在编译时并未明确知晓。在Java中,反射通常通过`java.lang.Class`类和相关的API来实现。本实例将...

    java反射-英文版反射规范

    ### Java反射机制详解 #### 一、概述 Java反射机制是一种强大的编程技术,它允许运行时检查类的信息并操作对象的内部结构。本篇将基于Sun公司的官方文档《Java™ Core Reflection API and Specification》(1997年...

    反射实例-JAVA反射机制

    ### 反射实例—JAVA反射机制 #### 一、反射概念及原理 反射在计算机科学领域,特别是程序设计中,是指程序有能力访问、检测和修改其自身的结构和行为。这一概念最早由Smith于1982年提出,并迅速应用于各种编程语言...

    java反射.pdf

    ### Java反射机制详解 #### 一、什么是Java反射? Java反射是Java编程语言的一个特性,它允许运行时检查和操作程序结构(类、字段、方法等)。反射的主要用途包括但不限于:动态实例化对象、访问私有成员、调用...

    java 反射 调用私有方法(有参数私有方法)获取私有属性值

    Java反射是Java语言提供的一种强大的动态类型特性,它允许程序在运行时检查类、接口、字段和方法的信息,并且能够动态地创建对象和调用方法。这个能力使得开发者可以突破静态类型的束缚,实现一些在编译时期无法完成...

    java反射源代码

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

    java 反射机制例子

    ### Java反射机制详解 #### 一、反射的基本概念与历史背景 反射的概念最早由Smith在1982年提出,其核心思想是程序有能力访问、检测甚至修改自身的状态和行为。这种能力一经提出,迅速成为了计算机科学领域的研究...

    java 反射 报错 no such method exception

    ### Java反射机制与NoSuchMethodException详解 在Java编程中,反射是一种强大的机制,允许程序在运行时检查和修改自身结构和行为。然而,当开发者尝试使用反射调用一个不存在的方法时,便会遇到`java.lang....

    java反射获取所有属性,获取所有get方法,包括子类父类

    Java反射是Java编程语言中的一个强大工具,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。在Java中,反射主要用于在运行时分析类和对象,包括访问私有成员、调用私有方法、创建动态代理等。...

    利用java反射将json字符串转成对象.zip

    Java反射是Java编程语言中的一个强大工具,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。在给定的“利用java反射将json字符串转成对象”的主题中,我们将深入探讨如何借助反射机制将JSON...

    Java反射机制Demo

    ### Java反射机制详解 #### 一、什么是Java反射机制? Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的...

    北大青鸟java反射机制

    Java反射机制是Java编程语言中的一个强大工具,它允许程序在运行时检查并操作类、接口、字段和方法等对象。在"北大青鸟java反射机制"的学习资料中,我们将会深入探讨这一核心特性。 首先,我们要理解反射的核心概念...

    java反射

    ### Java反射机制详解 #### 一、引言 在Java编程语言中,反射(Reflection)是一种强大的工具,它允许程序在运行时访问类的信息,并能够动态地创建对象、调用方法以及获取字段值等。这种能力对于框架设计、代码...

Global site tag (gtag.js) - Google Analytics