JAVA学习笔记之反射机制

一、反射机制的概述

1、什么是反射机制

 动态获取信息以及动态调用对象的方法的功能称为Java语言的反射机制

 简单来说,反射机制指的是程序在运行时能够获取自身的信息。在java中,只要给定类的名字,那么就可以通过反射机制来获得类的所有信息,包括: 访问修饰符、父类、实现的接口、属性和方法的所有信息,并可在运行时创建对象、修改属性(包括私有的)、调用方法(包括私有的)。


2、提供的功能

 *在运行时判断一个对象所属的类
 *在运行时构造任意一个类的对象
 *在运行时判断一个类所具有的成员变量和方法
 *在运行时调用任意一个对象的方法

3、作用

 首先简单了解两个概念

 *静态编译:在编译时确定类型,绑定对象,如:Student stu=new Student(“zhang”,30);

 *动态编译:运行时才确定类型,绑定对象。如:Class.forName(“com.mysql.jadb.Driver.class”).newInstance();(后续介绍这个创建对象的语法)

 动态编译最大限度发挥了java的灵活性,体现了多态的应用,用以降低类之间的耦合性。

反射机制的优点就是可以实现动态创建对象和编译,体现出很大的灵活性,特别是在J2EE中。它的缺点是对性能有影响。使用反射基本上是一种解释操作,这类操作总是鳗鱼直接执行的相同操作。

二、Class对象

1、class对象是Reflection故事起源。想要操作类中的属性和方法,都必须从class对象开始
 *类是程序的一部分,每个类都有一个class对象。每当编写并且编译一个新类,就产生与之对应的一个Class对象。
 *Class类没有公共构造方法。Class对象在加载类时由java虚拟机及通过调用类加载器中的方法自动构造,因此不能显式声明一个Class对象

2、获取Class对象的方式
 *object.getClass()---获得指定实例的Class对象
 *class.getSuperClass---获得当前Class的继承类的class
 *.Class语法---.Class直接获取
 *Class.forName(类名)---用得较多,用Class的静态方法,传入类的全称即可
 *Primitive.TYPE---基本数据类型的包装类获取Class方式

三、JAVA反射API

1、java.lang包:
 *Class<T>:表示一个正在运行的Java应用程序中的类和接口,是reflection的起源

2、java.lang.reflect包:
 *Field类:代表成员变量(类的属性)
 *Method类:代表类的方法
 *Constructor类:代表类的构造方法。
 *Array类:提供了动态创建数组,以及访问数组的元素的静态方法

四、通过反射实例化对象

1、实例化无参构造函数的两种方式:
 *class.newInstance(); //通过Class对象的newInstance()方法直接创建对象,这种实例化对象的方式会默认调用无参的构造方法
 *class.getConstructor(new Class[]{}).newInstance(new Object[]{}) //通过Class对象的getConstructor方法获得对应的构造方法,再通过返回的constructor对象的newInstance()创建实例

2、实例化带构造函数的对象
 *class.getConstructor(Class<?>...parameterTypes).newInstance(Object...intargs)

五、通过反射获取并调用方法

1、获得当前类及超类所有的public Method
 *Method[] arrMethods=classType.getMethods();

2、获得当前类及超类指定的public Method
 *Method methods=classType.getMethod(String name,Class<?>...parameterTypes);

3、获得当前类声明的所有Method
 *Method[] arrMethods=classType.getDeclareMethods();

4、获得当前类声明的指定的Method
 *Method methods=classType.getDeclareMethods(String name,Class<?>...parameterTypes);

5、通过反射动态运行指定Method
 *Object obj=method.invoke(Object object,Object...args)

六、通过反射获取并调用方法

1、获得当前类及超类所有的public Field
 *Field[] arrFields=classType.getFields();

2、获得当前类及超类指定的public Method
 *Field[] Field=classType.getFields(String name);

3、获得当前类声明的所有Method
 *Field[] arrFields=classType.getDeclareFields();

4、获得当前类申明的指定的Method
 *Field Field=classType.getDeclareFields(String name);

5、通过反射动态设定Field的值
 *Field.set(Object object,Object values)

6、通过反射动态获得Field的值
 *Field.get(Object object)

七、案例

1、使用反射机制的步骤:

 *获得类对应的Class对象

 *通过Class对象,调用相关的构造方法创建类的对象

 *通过反射来调用方法或属性

2、案例代码

package com.huanbao.reflection;


import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;


public class ReflectionDemo{


	public static void main(String[] args) throws Exception {
		//获得Employee类关联的Class对象
		Class<?> classType=Class.forName("com.huanbao.reflection.Employee");
		
		//通过反射机制来构造Employee的实例对象(默认调用无参的构造方法)
		Employee employee=(Employee) classType.newInstance();
		
		//调用指定的构造方法来构造对象(同样调用无参构造方法)
		Constructor<?> constructor=classType.getConstructor(new Class[] {});
		Employee employee1=(Employee) constructor.newInstance(new Object[] {});
		
		//调用指定的构造方法来构造对象(调用带参数的构造方法)
		constructor=classType.getConstructor(new Class[] {String.class,int.class});//参数类型所对应的class对象
		Employee employee2=(Employee) constructor.newInstance(new Object[] {"zhangsna",30});
		
		//获取Class对象所有的方法,包括私有的,然后输出方法名作测试
		Method[] methods=classType.getDeclaredMethods();
		for(Method method:methods) {
			System.out.println(method.getName());
		}
		
		//获取Class对象所指定的方法,包括私有的,然后打印输出方法名作测试
		Method method=classType.getDeclaredMethod("toString", new Class[] {});
		System.out.println(method.getName());
		//方法的调用(调用toString方法)
		String test=(String) method.invoke(employee, new Object[] {});
		System.out.println(test);
		
		//获取Class所指定的属性,包括私有的
		Field field=classType.getDeclaredField("name");
		field.setAccessible(true);//由于是私有的,必须要设置访问权限,才可以实现属性的操作
		field.set(employee, "王五");
		System.out.println(field.get(employee));
	}


}
class Employee{
	private String name;
	private int age;
	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;
	}
	public Employee() {
		System.out.println("无参构造方法");
	}
	public Employee(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	@Override
	public String toString() {
		return "Employee [name=" + name + ", age=" + age + "]";
	}
	
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值