java的动态性---反射

动态语言是值 程序在运行是能够改变程序结构和变量类型的语言 

js 和python 就是动态语言

c和c++ 就不是 

java的动态性为他提供了类似的特性,使得功能变得强大

动态性的实现有两个 

1,反射

2,序列化和反序列化

***********************************

反射 reflection

反射是指 在程序运行是, 仍然可以加载一些你只知道名字的类;

Class clazz = Class.forName("annotation.Student");

加载完类以后,就会在堆内存里产生一个class 类型的对象,这个对象就包含了完整的类的结构信息,我们就可以通过这个对象看到类的结构, 这个对象就像一面镜子, 称之为反射。

所有的类被加载后都会生产一个Class 对象,变成一张图纸, 而这张图纸不会被重复生成

*********************

通过反射获取 类名 类的属性,方法 ,构造器

package annotation;

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




public class Client {
	public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException, NoSuchMethodException {
		String path= "annotation.Student";
		Class clazz = Class.forName(path);
		
		// 获取类名
		String str1= clazz.getName();
		String str2= clazz.getSimpleName();
		System.out.println(str1);
		System.out.println(str2);
		
		// 获取字段
	//	Field [] fields = clazz.getFields(); // 获取公开声明的字段
		Field [] fields = clazz.getDeclaredFields(); // 获取公开声明的字段
		Field  field1 = clazz.getDeclaredField("name"); // 获取公开声明的字段
		for (Field field : fields) {
			System.out.println(field);
		}
		System.out.println(field1);
		System.out.println("*********************methods");
		// 获取方法
		Method [] methods= clazz.getMethods();
		for (Method method : methods) {
			System.out.println(method);
		}
		System.out.println("*********************method单个的,有参和无参的区别");
		Method method1= clazz.getMethod("getName");
		Method method2= clazz.getMethod("setName",String.class);
		System.out.println(method1);
		System.out.println(method2);
		
		System.out.println("*********************构造器");
		// 获取构造器
		Constructor[] constructors= clazz.getDeclaredConstructors();
		for (Constructor constructor : constructors) {
			System.out.println(constructor);
		}
		System.out.println("*********************Constructor单个的,有参和无参的区别");
		Constructor constructor1= clazz.getDeclaredConstructor(null);
		Constructor constructor2= clazz.getDeclaredConstructor(String.class,int.class,int.class);
		System.out.println(constructor1);
		System.out.println(constructor2);
		
		
	}
}

反射的三个应用

package annotation;


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

public class Client1 {

	public static void main(String[] args)throws ClassNotFoundException, NoSuchFieldException, SecurityException, NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException  {
		// TODO Auto-generated method stub
		String path= "annotation.Student";
		Class clazz = Class.forName(path);
		
		// 通过反射构造对象
		Student xiaoming = (Student) clazz.newInstance();  // 其实是调用了无参数构造器
		System.out.println(xiaoming);
		// .......
		Constructor constructor= clazz.getConstructor(String.class,int.class,int.class); // 使用反射来获取构造器;然后根据构造器
		Student xiaogang = (Student) constructor.newInstance("xiaogang",20,1000);
		System.out.println(xiaogang);
		
		
		// 通过反射调用普通方法
		
		Student xiaohong = (Student) clazz.newInstance();  // 其实是调用了无参数构造器
		Method setName= clazz.getDeclaredMethod("setName", String.class); // 通过反射获取方法
		setName.invoke(xiaohong,"小红"); // 通过反射调用, 这个后面会用在动态代理上面
		System.out.println(xiaohong.getName()); 
		
		System.out.println("(((((((((((((");
		// 通过反射设置属性
		Student xiaolv = (Student) clazz.newInstance();  // 其实是调用了无参数构造器
		Field f= clazz.getDeclaredField("name"); // 通过反射获取字段
		f.setAccessible(true);  //停止安全检查
		f.set(xiaolv, "小驴"); //通过 字段反射的方法 来设置名字
		System.out.println(xiaolv.getName()); // 正常
		System.out.println(f.get(xiaolv));//通过 字段反射的方法 来得到名字
		
	}

}

 

 

********************

反射的三个话题

1,反射的性能问题

反射机制对我们性能有一定的影响, 反射带来方便,弊端就是性能消耗比较厉害

可以通过setAccessible 设置为true 禁止安全检查提高运行的概率;

普通方法的时间为1, 那么反射 执行的时间就是30倍,跳过安全检查就是14倍左右,

2,反射操作注解

注解的例子就是 

3,反射操作泛型

编译器会使用泛型来完成编译,而一旦编译完成,那么将擦除泛型;

不常用就不 写代码了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值