反射

定义概念

 概念:反射就是将Java类中的各种成分映射成相应的Java类	

1、获取Class的3种方式

	对象 s=new 对象();
	s.getClass();
	类名.class;
	Class.forName("java.lang.String");//主要用这种。
	Java中有9个预定义的Class实例对象(8个基本数据类型和void)void.class也是可以的。

2、练习-方法大全

public static void main(String[] args) throws Exception{
		//不同方式获取class
		String str1="abc";
		Class cls1=str1.getClass();
		Class cls2=String.class;
		Class cls3=Class.forName("java.lang.String");
		//结论:不同方法获取到的Class是相同的
		System.out.println(cls1==cls2);//true
		System.out.println(cls1==cls3);//true
		
		//几种方法
		System.out.println(cls1.isPrimitive());//String不是基本类型false
		System.out.println(int.class.isPrimitive());//int是基本类型true
		System.out.println(int.class==Integer.class);//false,是不同的类型
		System.out.println(int.class==Integer.TYPE);//Integer所代表的基本数据类型Class结果是true
		System.out.println(int[].class.isPrimitive());//int数组类型不是基本类型false
		System.out.println(int[].class.isArray());//int数组类型是数组true

		//获取构造方法
		//参数是StringBuffer的
		Constructor constructor = String.class.getConstructor(StringBuffer.class);
		String newInstance = (String) constructor.newInstance(new StringBuffer("abc"));
		System.out.println(newInstance);
		//得到所有构造方法
		Constructor[] constructors = String.class.getConstructors();
		//得到默认的构造方法
		String newInstance2 = String.class.newInstance();

		//获取属性
		User u=new User(1,2);
		Field fieldX = u.getClass().getField("x");
		System.out.println(fieldX.get(u));
		Field fieldY = u.getClass().getDeclaredField("y");//获取私有属性,非私有的也能获取到
		fieldY.setAccessible(true);//授权
		System.out.println(fieldY.get(u));

		//将u反射,修改字段值
		changeStringValue(u);
		
		//获取方法
		//参数是方法名和参数类型
		Method method = String.class.getMethod("charAt", int.class);
		//如果传入的第一个参数是null,说明调用的是静态方法,不需要对象既可以调用(例如这里的str1可以写成null)
		Object invoke = method.invoke(str1, 1);
		System.out.println(invoke);
		Object invoke2 = method.invoke(str1, new Object[] {2});
		System.out.println(invoke2);

		//在这个main方法中调用另一个类的main方法,args[0]是那个类的全路径
		//需要做一件事,在run as config中添加参数,也就是类的全路径如下图所以
		//另一个类中就可以在main方法中循环遍历args[],输出每一个元素
		String arg=args[0];
		Method method2 = Class.forName(arg).getMethod("main", String[].class);
		//main方法是静态的,所以第一个参数传null
		//下面2中执行方法都可以。任选其一
		//method2.invoke(null, new Object[] {new String[] {"111","222","333"}});
		method2.invoke(null, (Object)new String[] {"111","222","333"});

		//数组
		int[] a1=new int[]{1,2,3};
		int[] a2=new int[4];
		int[][] a3=new int[2][3];
		String[] a4=new String[]{"a","b","c"};
		
		System.out.println(a1.getClass()==a2.getClass());//true
		System.out.println(a1.getClass().getName());//[I
		System.out.println(a1.getClass().getSuperclass().getName());//java.lang.Object
		System.out.println(a3.getClass().getSuperclass().getName());//java.lang.Object
		System.out.println(a4.getClass().getSuperclass().getName());//java.lang.Object
		
		//		Object o1=a1;
		//		Object o2=a4;
		//		Object[] o3=a3;
		//		Object[] o4=a4;
		
		//asList()方法:传int数组,List中每个元素都是数组,而传String数组,每个元素都是String
		System.out.println(Arrays.asList(a1));
		System.out.println(Arrays.asList(a4));
		//数组的反射
		printObject(a4);//传的数组循环打印
		printObject("xyz");//传的字符串直接打印

		//内存泄漏的例子
		T1 u1=new T1(1,2);
		T1 u2=new T1(1,2);
		//前提是HashSet中重写了hashcode和equals方法
		Collection c=new HashSet();
		c.add(u1);
		c.add(u2);
		//内存泄漏:由于改了u1中的字段值,所以u1的hashCode值也跟着改变了,在内存中会多出来一个内存地址,以前的不用了也没有进行回收。
		u1.i=3;
		c.remove(u1);
		System.out.println(c.size());


		//读取配置文件,通过反射的方式创建对象
		InputStream is =new FileInputStream("config.properties");
		Properties p=new Properties();
		p.load(is);
		is.close();
		//className=java.util.ArrayList
		String className=p.getProperty("className");
		//反射成功集合类
		Collection collection = (Collection) Class.forName(className).newInstance();


}

//通过反射的方法,将类中的字符串类型字段改变值
	private static void changeStringValue(Object obj) throws Exception {
		Field[] fields = obj.getClass().getFields();
		for(Field field:fields) {
			if(field.getType()==String.class) {
				String s = (String) field.get(obj);
				field.set(obj, s.replace("b","a"));
			}
		}
	}
//数组的反射。。。
private static void printObject(Object obj) {
		Class objClass = obj.getClass();
		//如果是数组遍历打印,否则直接打印
		if(objClass.isArray()) {
			int length = Array.getLength(obj);
			for(int i=0;i<length;i++) {
				System.out.println(Array.get(obj, i));
			}
		}else {
			System.out.println(obj);
		}
	}

给main方法添加请求参数:
在这里插入图片描述
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值