Java基础(二十四)反射技术

Junit单元测试

/*
 * 1.在运行方法上,添加注解@Test
 * 2.右键以junit运行
 * 3.@Before 测试方法前执行的代码
 * 4.@After 测试方法后执行的代码*/
public class JunitDemo {
	@Test
	public void demo1() {
	 System.out.println("demo1....");
 }
	@Before
	 public void demo3() {
		System.out.println("before");
	}
	@Test
	public void demo2() {
		System.out.println("demo2.....");
	}
	
	@After
	public void demo4() {
		System.out.println("after");
	}
}

反射概述:
java反射机制是在运行状态中,对指定的类、任意的方法或任意的字段进行操作,这种动态获取的信息以及动态调用对象方法的功能称为Java语言的反射机制
在运行时通过代码操作类
Class类
Constructor 构造
Method方法
Field 字段
instance 实例
invoke 执行

准备数据


import java.io.Serializable;

/*提供JavaBean,用于之后反射操作
 * JavaBean规范
 * 1.提供私有字段,例如private String id;
 * 2.必须提供getter或setter方法
 * 3.提供无参构造
 * 4.必须实现序列化接口
 * java.io.serializable*/
public class Bean  implements Serializable{
private String id;
private String ClassName;
public Bean() {
	// TODO Auto-generated constructor stub
}
public String getId() {
	return id;
}
public void setId(String id) {
	this.id = id;
}
public String getClassName() {
	return ClassName;
}
public void setClassName(String className) {
	ClassName = className;
}

}

class获得方式
Java提供3种不同的方式获得Class对象
方式1:通过字符串(全限定类)获得
格式: Class clazz=Class.forName(“字符串”);
全限定类名:包名+类名
2:通过Java类型获得
格式:Class clazz=类型.class
3.通过实例对象获得
格式:Class clazz=obj.getClass();
应用场景:
方式1:之后开发中,从配置文件中,获得全限定类名,并通过反射进行所有操作
方式2:确定构造方法、普通方法形参列表时,需要通过类型获得
方式3:方法内部通过变量名获得


/*Java提供3种不同的方式获得Class对象
方式1:通过字符串(全限定类)获得
格式: Class clazz=Class.forName("字符串");
全限定类名:包名+类名
2:通过Java类型获得
格式:Class clazz=类型.class
3.通过实例对象获得
格式:Class clazz=obj.getClass();*/
public class ClassDemo {
@Test
 public void demo1() throws ReflectiveOperationException {
	Class clazz=Class.forName("com.itxuexi_01.Bean");
	System.out.println(clazz);
}
@Test
public void demo2() {
	Class clazz=Bean.class;
	System.out.println(clazz);
}
@Test
public void demo3() {
	Bean b=new Bean();
	Class clazz=b.getClass();
	System.out.println(clazz);
			
}
}

构造方法与实例
通过有参/无参构造获得实例
1.获得Class对象
2.获得构造对象 getConstructor
3.获得实例 newInstance

public class MethodDemo {
//Bean bean =new Bean();
	//1.获得Class对象
	@Test
	public void demo1() throws Exception {
	Class clazz=Class.forName("com.itxuexi_01.Bean");
	//2.获得构造对象 getConstructor:相当于Bean()
	Constructor cons=clazz.getConstructor();
	//3.获得实例 newInstance:相当于new Bean()
	Object obj=cons.newInstance();
	}
	@Test
	public void demo2() throws Exception {
		Class clazz=Class.forName("com.itxuexi_01.Bean");
		Constructor cons=clazz.getConstructor(String.class);
		Object obj=cons.newInstance("it001");
		System.out.println(obj);
	}
	
}

通过私有构造方法创建实例对象
1.获得Class对象
2.获得指定形参私有构造
clazz.getConstructor(…)获得指定对象的指定的public构造方法
clazz.getDeclaredConstructor(String .class,String .class)获得指定对象的所有构造方法
3.通知JVM,运行实例化私有构造(默认不允许)
cons.setAccessible(true);
4.创建实例,并设置实际参数

@Test
	public void demo3() throws Exception{
		//获得class对象
		Class clazz=Class.forName("com.itxuexi_01.Bean");
		//获得指定形参的私有构造
		 Constructor con=clazz.getDeclaredConstructor(String.class,String.class);
		 //通知JVM,运行实例化私有构造
		 con.setAccessible(true);
		 //创建实例并设置参数
		 Object obj=con.newInstance("it001","名字");
		 System.out.println(obj);
	}

普通方法–public方法
1。获得实例
2.通过setId方法设置数据
2.1获得方法,需要明确形参列表
getMethod()
2.2执行方法,bean.SetId
确定实例对象,并确定执行方法,具体实际参数
method.invoke

@Test
	public void demo1() throws Exception {
		//1.获得实例
		Class clazz=Class.forName("com.itxuexi_01.Bean");
		Object obj=clazz.newInstance();
		//获得方法
		Method method=clazz.getMethod("setId", String.class);
		method.invoke(obj, "it001");
		
		Method getIdMethod =clazz.getMethod("getId");
		String str=(String) getIdMethod.invoke(obj);
		System.out.println(str);
		System.out.println(obj);
		
	}

执行bean的私有方法
1.获得实例
2.执行方法
2.1获得方法
clazz.getMethod只能获取public类型方法
clazz.getDeclaredMethod()获得已声明的方法
2.2强制设置允许访问私有方法(暴力)
2.3执行方法

	Class clazz=Class.forName("com.itxuexi_01.Bean");
	Object obj=clazz.newInstance();
	//2.1获得方法
	Method method=clazz.getDeclaredMethod("show", int.class);
	//2.2强制设置允许访问私有方法(暴力)
	method.setAccessible(true);
	Object sss=method.invoke(obj, 20);
	System.out.println(sss);
	System.out.println(obj);
	
}

main方法与执行
执行静态方法main
1.获得class对象
2.获得main方法
3.执行main方法
参数1:为实例对象(变量名)
参数2:main方法执行的实际参数
可变参数执行时,JVM内部将传递实参数组打散,变成多个参数
数组参数需要特殊处理
方式1:将String[]转换成Object可变参数将不处理
方式2:将提供一个二维数组,args将作为二维数组的第一个数
Arrays.toString(args)将指定的数组转换为字符串

@Test
public void demo2() throws Exception {
	Class clazz=Class.forName("com.itxuexi_01.Bean");
	Method method=clazz.getMethod("main", String[].class);
	String[]arr= {"123","abc","xxx"};
	method.invoke(null, (Object)arr);
	method.invoke(null, new Object[]{arr});
}

public操作
1.获得实例对象
2.给字段赋值
3.获得字段

Class clazz=Class.forName("com.itxuexi_01.Bean");
	Object obj=clazz.newInstance();
	//给字段赋值
	Field field=clazz.getField("description");
	field.set(obj, "描述");
	//获得字段
	String str=(String) field.get(obj);
	System.out.println(str);

私有字段
1.获得实例
2.获得声明的字段
getDeclaredField(获得声明字段含私有)
3.设置运行访问私有(暴力)
4.设置数据
5.获得数据
注意是否在测试方法上写@Test不然出现错误

Class clazz=Class.forName("com.itxuexi_01.Bean");
	Object obj1=clazz.newInstance();
	//2.获得声明的字段 getDeclaredField(获得声明字段含私有) 
	Field field=clazz.getDeclaredField("ClassName");
	field.setAccessible(true);
	field.set(obj1, "班级");
	//System.out.println(obj1);
	
	String ClassName=(String) field.get(obj1);
	System.out.println(ClassName);

Properties类表示了一个持久的属性集,可保存在流中或从流中加载,属性列表中每个键及其对应的值都是一个字符串
特点:
1.Map接口的子类,map中的方法都可以用
2.该集合没有泛型。键值都是字符串
3.它是一个可以持久化的属性集,键值可以存储到集合中,也可以存储到持久化的设备上。键值的来源也可以是持久化的设备
4.有和技术流相结合的方法
Object setProperty(String key, String value)
调用 Hashtable 的方法 put。
Set stringPropertyNames()
返回此属性列表中的键集,其中该键及其对应值是字符串,如果在主属性列表中未找到同名的键,则还包括默认属性列表中不同的键。
String getProperty(String key)
用指定的键在此属性列表中搜索属性。


		Properties props=new Properties();
		//2.设置数据setProperty()
		props.setProperty("k001","v001");
		props.setProperty("k002", "v002");
		props.setProperty("k003", "v003");
		props.setProperty("k004", "v004");
		//3.得指定名称的数据
		String val=props.getProperty("k001");
		System.out.println(val);
		Set<String> names=props.stringPropertyNames();
		for(String name:names) {
			String value=props.getProperty(name);
			System.out.println(name+":"+value);

存储Store
加载load

Test
public void demo1() throws Exception, FileNotFoundException {
	//创建properties对象
	Properties pro= new Properties();
	pro.setProperty("k001", "v001黑马");
	pro.setProperty("k002", "v002程序员");
	pro.setProperty("k003", "v003摸摸你");
	Writer wri=new OutputStreamWriter(new FileOutputStream("1.properties"),"UTF-8");
	pro.store(wri, "描述");
	wri.close();
}
@Test
public void demo2() throws Exception, FileNotFoundException {
	Reader read=new InputStreamReader(new FileInputStream("1.properties"),"UTF-8");
	
	Properties pro=new Properties();
	pro.load(read);
	for(String name:pro.stringPropertyNames()) {
		String value =pro.getProperty(name);
		System.out.println(name+":"+value);
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值