JAVA基础——java动态性之反射

一、简介:

    java不算是动态语言,但是却含有一些动态性机制功能。体现java动态性的有:反射机制、动态编译、动态执行javascript代码和动态字节码操作等。在这里介绍一下java动态性中的反射机制。反射机制是在java程序运行状态中,可以动态的记载类,对于已经加载的类,可以知道这个类的所有属性和方法,也可以操作其对象的相关属性和方法。加载类之后会在堆内存中生成该类的一个Class类型的对象,该对象中包含该类的结构信息,结构信息和类的相关信息形成一种映射关系,这就体现了类本身和Class对象的反射关系。

二、操作:

    1、Class类型对象的获取:

    获取Class类型对象有三种方法,如下语句:

<pre class="java" name="code">	Class clazz = Class.forName(path);
	Class strClazz = String.class;
	Class strClazz2 = path.getClass(); 
 

    其中常用的还是Class.forName(对象名)这个方法。

    2、利用反射API获取和操作类的相关信息。

    其核心代码如下:

	Class<User> clazz = (Class<User>) Class.forName(path);

	//通过反射API调用构造方法,构造对象
	//1、调用User无参构造方法生成新对象
	User u = clazz.newInstance();
	//2、调用User指定参数的构造方法生成新对象。
	Constructor<User> c = 
		clazz.getDeclaredConstructor(int.class,int.class,String.class);
	User u2 = c.newInstance(1001,18,"高淇二");

	//通过反射API调用普通方法
	User u3 = clazz.newInstance();
	Method method = clazz.getDeclaredMethod("setUname", String.class);
	method.invoke(u3, "高淇三");   //相当于u3.setUname("高淇三");

	//通过反射API操作属性
	User u4 = clazz.newInstance();
	Field f = clazz.getDeclaredField("uname");
	f.setAccessible(true); //指定属性不需要做安全检查了,可以直接访问
	f.set(u4, "高淇四");		//通过反射直接写属性

    下边说明有关setAccessible方法,一般情况下反射只可以访问类中的非静态成员,如果要访问类中的静态成员,需要通过setAccessible方法设置该属性可以直接访问不需要做安全检查;反射的一大缺点就是需要速度慢,主要就是在于每次访问都需要做安全检查,因此如果需要避免反射速度慢的缺点,必要时候也会牺牲安全因素,提高运行速度,这时就需要通过setAccessible方法进行设置。

    3、通过反射获取泛型:

    核心代码如下:

	//获得指定方法参数泛型信息
	Method m = Demo04.class.getMethod("test01", Map.class,List.class);
	Type[] t = m.getGenericParameterTypes();
	for (Type paramType : t) {
		System.out.println("#"+paramType);
		if(paramType instanceof ParameterizedType){
			Type[] genericTypes = ((ParameterizedType) paramType).getActualTypeArguments();
			for (Type genericType : genericTypes) {
				System.out.println("泛型类型:"+genericType);
			}
		}
	}

	//获得指定方法返回值泛型信息
	Method m2 = Demo04.class.getMethod("test02", null);
	Type returnType = m2.getGenericReturnType();
	if(returnType instanceof ParameterizedType){
		Type[] genericTypes = ((ParameterizedType) returnType).getActualTypeArguments();
		for (Type genericType : genericTypes) {
			System.out.println("返回值,泛型类型:"+genericType);
		}	
	}

    4、反射操作注解:

    有关操作注解:这里定义了两个自定义的注解和一个操作类,SxtTable、SxtField以及Demo类,用于模拟代码信息生成数据库对应表信息的过程,其相关代码如下:

    自定义注解SxtTable:

@Target(value={ElementType.TYPE}) //修饰范围为类或接口等。
@Retention(RetentionPolicy.RUNTIME) //定义注解的生命周期。
public @interface SxtTable {
	String value();
}

    自定义注解SxtField:

@Target(value={ElementType.FIELD}) //修饰范围为类型成员。
@Retention(RetentionPolicy.RUNTIME) //定义注解的生命周期。
public @interface SxtField {
	String columnName();
	String type();
	int length();
}

    操作类:

@SxtTable("tb_student")
public class SxtStudent {

	@SxtField(columnName="id",type="int",length=10)
	private int id;
	@SxtField(columnName="sname",type="varchar",length=10)
	private String studentName;
	@SxtField(columnName="age",type="int",length=3)
	private int age;
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getStudentName() {
		return studentName;
	}
	public void setStudentName(String studentName) {
		this.studentName = studentName;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
}


三、总结:

    通过反射初步认识了有关java动态性的一些操作,但是有关反射的运用远远不止这些,反射是java中非常有力的一个功能,当然反射也有自己的一些缺陷,在运用中需要权衡好其利弊,尽量做到将其利益最大化。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值