`
xifangyuhui
  • 浏览: 188576 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java反射笔记(1)

阅读更多

感谢张龙老师的视频:http://www.verycd.com/topics/2838873/

 

在Java运行时环境中,对于任意一个类,通过反射能够知道这个类有哪些属性和方法,并且构造这个类的实例,对于任意一个类,能调用任意一个方法。这种动态地获取类的信息以及动态调用对象方法的功能来自于JAVA语言的反射(Reflection)机制。

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

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

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

3、在运行时判断任意一个类所具有的成员变量和方法

4、在运行时调用任意一个对象的方法

 

动态语言 :程序运行时,允许改变程序结构或者变量类型。Perl,Python,Ruby都是动态语言,而C#C++,JAVA都不是动态语言。

JAVA具有非常突出的动态的相关机制:Reflection,在java中是指可以用于在运行时加载、探知、使用编译期间完全未知的classes,换句话说,java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但是不包含methods定义),并生成该类的对象实体、或对其fields设值、或唤起其methods,这种“看透class”的能力被称为introspection。

JDK中,实现Reflection的类位于java.lang.Reflect包中:

Class类:代表一个类

Filed类:代表类的成员变量(成员变量也称为类的属性)

Method类:代表类的方法

Constructor:代表类的构造方法

Array类:提供了动态创建数组,以及访问数组的元素的静态方法


java的反射必须从Class类开始,Class类位于java.lang包中。

 

public class DumpMethods {
	
	public int add(int a, int b) {
		return a+b;
	}
	
	public void echo(String mesg) {
		System.out.println(mesg);
	}
	/*
	 * 通过反射调用DumpMethods的add方法和echo方法
	 */
	public static void main(String[] args) {
		
		try {
			//首先通过类名获得该类的class对象,Class类是java反射的入口点
//			Class<?> classType = Class.forName(args[0]);
			//Class中的每一个方法都会对应一个Method实例
//			Method[] methods = classType.getDeclaredMethods();
			Class classType = DumpMethods.class;
			//通过Class的newInstance()获得该Class对象代表的class的实例
			Object dumpObj = classType.newInstance();
			//下面两句代码同直接调用DumpMethod实例的add(100,200),通过反射调用add方法,首先要获得该add方法
			//代表的Method对象,是利用Class类的getMethod方法,并且传递方法名和该方法的Class参数数组,只能获取public的方法实例。
			//另外在调用该方法时,调用该Method对象的invoke方法,并将该方法所属的实例和参数的对象数组传入,返回一个Object对象
			Method addMethod = classType.getMethod("add", new Class[]{int.class, int.class});
			Object resultObj = addMethod.invoke(dumpObj, new Object[]{100,200});
			System.out.println(resultObj);
			
			Method echoMethod = classType.getMethod("echo", new Class[]{String.class});
			Object obj = echoMethod.invoke(dumpObj, new Object[]{"zhutong is a good boy"});
			
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
	}
}

 

注意Class对象的newInstance()只会调用Class对象对应的class的不带参数的构造方法,如果该class中的构造函数被重载了,那么直接使用Class对象的newInstance方法来构造实例是不成功的。

那我们还想得到Class的实例怎么办呢?和Class,Method类似,在一个类中,每个构造方法也对应了一个对象,即Constructor对象,可以通过Class的getConstructor (Class <?>... parameterTypes) 方法来获得Class对应类的某个构造方法,为什么是某个呢?构造方法重载仅仅是它们的参数不一样,可能是参数个数,参数类型以及参数顺序不一样,这里通过getConstructor (Class <?>... parameterTypes) 方法的参数中的Class数组来获得不同的Constructor对象,和获得Method对象一样,需要将构造方法的参数的类型构造为一个Class数组通过这个Class数组来判断获取的到底是哪个构造方法。那么问一个小问题,如果要通过getConstructor方法来调用不带参数的构造方法怎么办呢,很简单,传递一个空的Class数组不就行啦。

怎么通过Constructor来获得Class的实例呢?在Constructor中也包含了一个newInstance (Object ... initargs) 方法,但是该方法带有一个Object可变数组作为参数,当然就是传递给构造函数的参数啦,这里的Object可变参数的长度一定是与Class对象调用getConstructor方法中传递的Class可变参数的长度一致的,道理很简单,那么如何给空的构造方法传参数呢?呵呵,大家都懂的。。。

 

好了,通过反射现在可以在运行时得到类的实例,得到并且动态调用类的方法,以及得到带参数的构造方法并且进行实例化,那么我们可以得到类的字段吗?呵呵,当然可以,方法有Method对应,构造方法有Constructor对应,字段也有Field对应,Class中有两个方法:

 

Field getDeclaredField (String  name) 通过字段名来获得该字段对应的Field对象
Field []

getDeclaredFields ()  返回该类中所有的Field对象,以数组返回

 

 

代码:

public class ReflectTester {
	/*
	 * 利用反射机制动态生成一个对象的object的克隆对象
	 */
	public Object copy(Object object) throws Exception {
		//获得对象所属的Class对象
		Class classType = object.getClass();
		System.out.println("class: " + classType);
		//通过Class的getConstructor方法获得某个构造方法,并且调用newInstance()方法构造对象
		Customer customer = (Customer) classType.getConstructor(new Class[]{}).newInstance(new Object[]{});
		//获得类的所有字段对应的Field对象
		Field[] fields = classType.getDeclaredFields();
		for(int i=0; i<fields.length; i++) {
			Field field = fields[i];
			String fieldName = field.getName();
			String firstLetter = fieldName.substring(0, 1).toUpperCase();
			//通过field.getName()获取字段的名字,并构造getXXX和setXXX方法
			String getMethodStr = "get" + firstLetter + fieldName.substring(1);
			String setMethodStr = "set" + firstLetter + fieldName.substring(1);
			//通过调用Class的getMethod方法,并传入方法名和参数Class数组得到指定方法的Method对象
			Method getMethod = classType.getMethod(getMethodStr, new Class[]{});
			Method setMethod = classType.getMethod(setMethodStr, new Class[]{field.getType()});
			//通过调用传入地对象object的getXXX方法获得指定的字段值
			Object value = getMethod.invoke(object, new Object[]{});
			System.out.println(fieldName + ":" + value);
			//通过调用新创建的对象object的setXXX方法设置指定的字段值
			setMethod.invoke(customer, new Object[]{value});
		}
		return customer;
	}
	
	public static void main(String[] args) throws Exception {
		Customer customer = new Customer();
		customer.setId(200807058);
		customer.setAge(24);
		customer.setName("张三");
		ReflectTester rf = new ReflectTester();
		Customer newCustomer = null;
		newCustomer = (Customer) rf.copy(customer);
		System.out.println(newCustomer.getId() + ":" + newCustomer.getName() + ":" + newCustomer.getAge());
	}
}

class Customer {
	/*
	 * 默认的构造方法不能通过Class的getConstructor动态获得
	 */
	public Customer() {
		
	}
	private long id;
	private String name;
	private int 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 int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
}
 

 

0
0
分享到:
评论

相关推荐

    java反射笔记

    在“java反射笔记”这个主题中,我们将深入探讨反射的基础知识和常见用法。 首先,我们需要了解什么是反射。在Java中,反射是指在运行时获取类的信息(如类名、方法名、参数类型等)并动态调用对象的方法或访问其...

    java注解和反射的个人学习笔记

    java注解和反射的个人学习笔记

    JAVA反射笔记 md格式

    Java反射是Java编程语言中的一个强大特性,它允许运行时的程序访问并操作类、接口、字段和方法等对象,即使这些对象在编译时并未知。这为开发者提供了动态性,可以处理未知类型的对象,或者在运行时发现和调用类的...

    java学习笔记java反射机制

    java学习笔记java反射机制

    Java反射笔记源代码

    Java反射是Java编程语言中的一个强大特性,它允许程序在运行时检查类、接口、字段和方法的信息,并能动态地创建对象和调用方法。在深入理解Java反射之前,我们首先要明白,它属于元编程的一部分,即在编写程序时能够...

    JAVA 私塾笔记整理——反射机制(Reflection)

    Java反射机制是Java编程语言中的一个强大特性,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。这个特性使得Java具有了高度的灵活性和动态性,尤其是在处理对象、类、接口以及它们之间的关系...

    java学习笔记(java 反射机制 流 内存管理)

    本笔记主要涵盖了四个核心知识点:Java反射机制、流(I/O流)、内存管理和Java学习的基础。以下是对这些主题的详细阐述: 一、Java反射机制 Java反射机制是Java语言的一个强大特性,允许程序在运行时检查类、接口、...

    Java反射机制笔记(简单易懂)

    Java反射机制笔记 Java反射机制是Java语言中一个强大的功能,它允许程序在运行时检查和修改其自身的结构和行为。通过Java反射机制,我们可以在运行时获取类的信息,包括类的成员变量、方法、构造方法等,并可以动态...

    早期自学java反射知识笔记

    "Java 反射机制详解" Java 反射机制是 Java 语言中的一种强大功能,允许程序在运行时检查和修改自身的结构和行为。它主要用于动态的创建对象、调用方法和访问属性等。 ### Java 反射机制的定义 Java 反射机制是指...

    Java基础 学习笔记 Markdownr版

    本学习笔记主要涵盖了Java的基础知识,包括面向对象、集合、IO流、多线程、反射与动态代理以及Java 8的新特性等方面,旨在帮助初学者或有经验的开发者巩固和提升Java编程技能。 1. 面向对象(OOP):Java的核心是...

    java学习笔记markdown

    8. **反射机制**:探讨Java反射API的使用,包括动态获取类信息、创建对象、调用方法等功能,这对于理解和调试程序有很大的帮助。 9. **JVM内部机制**:简述Java虚拟机的工作原理,包括类加载、内存管理、垃圾回收...

    java全套笔记 来自狂神说java笔录.zip

    【Java编程语言基础】 Java是一种广泛使用的面向对象的编程...这些笔记内容全面覆盖了Java的基础和进阶知识,适合从零开始学习Java的人群,通过系统学习,可以建立起扎实的Java编程基础,为实战项目开发打下坚实基础。

    Java-反射笔记.pdf

    本笔记将深入探讨Java反射的原理、用途以及如何使用。 一、反射的概念与作用 反射是Java提供的一种能力,它允许程序在运行时动态地获取类的信息(如类名、方法名、参数类型等)并调用这些方法。这种动态性使得Java...

    java反射与动态代理笔记

    Java反射和动态代理是Java编程中的重要特性,它们在实现高度灵活和动态的代码执行方面发挥着关键作用。本文将深入探讨这两个概念及其在实际开发中的应用。 **Java反射** Java反射API允许程序在运行时检查类、接口...

    JAVA学习笔记 林信良

    《JAVA学习笔记》是林信良先生的一部深入浅出的Java编程教程,旨在帮助初学者和有一定经验的开发者巩固和提升Java编程技能。这本书涵盖了Java语言的基础到高级概念,是一份宝贵的自学资料。 首先,从基础部分开始,...

    java学习——java中的反射学习笔记.rar_java 反射

    本篇笔记将深入探讨Java反射的概念、重要性以及如何使用。 一、反射基础 1. 类加载:当Java虚拟机(JVM)加载一个类时,它会创建该类的Class对象。这个对象包含了关于类的所有信息,包括方法、字段、构造器等。...

    java笔记.zip

    尚硅谷康师傅java学习笔记。 、2020-4-5 java学习笔记 2020-4-6 java笔记 ---内部类 2020-4-6 java笔记 ---异常 2020-4-6 java笔记 --多线程 ...2020-4-21 java反射 2020-4-22 java8 新特性 2020-4-27 单元测试

    宋红康java笔记.rar

    1. **Java基础**:Java的基础语法是学习的起点,包括变量、数据类型、运算符、流程控制(如if语句、for循环、while循环)以及方法的定义和调用。理解这些基本元素是编写任何Java程序的基础。 2. **面向对象编程**:...

    李兴华java笔记

    1. **Java基础**:包括Java语言的基本语法、数据类型、控制结构(如if语句、switch语句、循环)、类与对象、封装、继承和多态等。这些是学习Java的基石,理解和掌握它们对于后续的学习至关重要。 2. **异常处理**:...

    达内Java_笔记整理.rar_Java 达内笔记_Java笔记_java 笔记_笔记_达内

    对于Java SE中的高级特性,例如反射、注解、动态代理等,笔记可能也会有详细讲解。这些特性使得Java具备了强大的元编程能力,可以用于实现许多复杂的设计模式。 除此之外,如果这份笔记还包含Java EE部分,那么Web...

Global site tag (gtag.js) - Google Analytics