什么是反射?为什么使用反射?


声明:Java中编译类型有两种

  • 静态编译:在编译时确定类型,绑定对象即通过
  • 动态编译:运行时确定类型,绑定对象。动态编译最大限度地发挥了Java的灵活性,体现了多态的应用,可以减低类之间的耦合性。

一、什么是反射

Java反射是Java被视为动态(或准动态)语言的一个关键性性质。这个机制允许程序在运行时透过Refiection APIs取得任何一个已知名称的class的内部信息,包括其modifiers(诸如public、static等)、superclass(例如Object)、实现之interfaces(例如Cloeable),也包括fields和method的所有信息,并可于运行时改变fields内容或唤起methods。
Refiection可以在运行时加载、探知、适应编译期间完全未知的classes。即Java程序可以加载一个运行时才得知名称的class,获取其完成构造,并生成其对象实体、或对其fields设值、或唤起methods。
反射(reflection)运行静态语言在运行时(runtime)检查、修改程序的结构与行为。
在静态语言汇总,使用一个变量时,必须知道它的类型。在Java中,变量的类型信息在编译时都保存到了class文件中,这样在运行时才能保证准确无误;换句话说,程序在运行时的行为都是固定的。如果想在运行时改变,就需要反射这东西了。

二、反射的特点

1.优点:主要是其动态性

  • 1.反射和new 都能创建用户对象,并且调用里面的方法,但是反射是针对字符串编程,new是针对实体类编程
  • 2.可以使框架更灵活
  • 3.可以深入到类的内部结构,去做一些操作。

2.缺点:主要是性能损失

三、实现Java反射机制的类都位于java.lang.reflect包中:

1、Class类:代表一个类
2、Field类:代表类的方法
3、Method:代表类的方法
4、Constructor类:代表类的构造方法
5、Array类:提供了动态创建数组,以及访问数组的元素的静态方法

四、使用场景

反射主要在构件框架时用的多
举例:

1.根据配置文件来动态生成相对的类型对象
2.根据注解来动态确定程序执行逻辑,如retrofit
3.生成动态代理
4.突破一些sdk的API接口限制(访问一个类的私有字段,私有方法等)	

5.替代方案

反射主要运用在构件框架上,平常项目中运用不到

  • 使用注解进行标记
  • 用过注解处理器(API)编译时帮我们生成相关代码
    特点:①:没用运行时性能损失,因为性能损失在编译器了;②:还保留了类型信息

六、案例

//案例一
package reflect;

import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflectTest {
	public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		//获取类的Class对象实例
		Class person = Class.forName("reflect.Person");
		//根据Class对象实例获取Constructor对象
		//Constructor constructor = person.getConstructor();
		//使用Class对象的newInstance方法获取反射类对象
		Object object = person.newInstance();
		//获取setName方法的Method对象,setName方法的参数类型为String
		Method setMethod = person.getMethod("setName", String.class);
		
	//	setMethod.setAccessible(true);
		//将参数值写入Method对象中
		Object setInvoke = setMethod.invoke(object, "李四");
		//获取Method对象中的getName方法
		Method getMethod = person.getMethod("getName");
		//获取Method对象中的getName方法的属性值
		Object getInvoke = getMethod.invoke(object);
		//输出得到的结果
		System.out.println(getInvoke);
		
	}
}
class Person implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private String name;
	private char sex;
	private int weight;
	private int height;
	private String bitth;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public char getSex() {
		return sex;
	}
	public void setSex(char sex) {
		this.sex = sex;
	}
	public int getWeight() {
		return weight;
	}
	public void setWeight(int weight) {
		this.weight = weight;
	}
	public int getHeight() {
		return height;
	}
	public void setHeight(int height) {
		this.height = height;
	}
	public String getBitth() {
		return bitth;
	}
	public void setBitth(String bitth) {
		this.bitth = bitth;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", sex=" + sex + ", weight=" + weight + ", height=" + height + ", bitth="
				+ bitth + "]";
	}
	
}


package reflect;

import java.io.Serializable;

public class ReflectTest2 {
	public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
		Class forName = Class.forName("reflect.Person1");
		Person1 p=(Person1)forName.newInstance();
		p.setName("张三");
		String s = p.toString();
		System.out.println(s);
	}
}


class Person1 implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private String name;
	private char sex;
	private int weight;
	private int height;
	private String bitth;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public char getSex() {
		return sex;
	}
	public void setSex(char sex) {
		this.sex = sex;
	}
	public int getWeight() {
		return weight;
	}
	public void setWeight(int weight) {
		this.weight = weight;
	}
	public int getHeight() {
		return height;
	}
	public void setHeight(int height) {
		this.height = height;
	}
	public String getBitth() {
		return bitth;
	}
	public void setBitth(String bitth) {
		this.bitth = bitth;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", sex=" + sex + ", weight=" + weight + ", height=" + height + ", bitth="
				+ bitth + "]";
	}
	
}


  • 5
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值