java基础之反射

反射基础:

文章目录结构

1、获取Class实例的常用方式
2、获取field属性的方式
(1)获取运行时类及其父类中声明为public的的属性
(2)获取运行时类本身的所有声明的属性
·获取类的属性类型及其属性名称
(3)获取指定属性,并且对指定的属性进行相应的赋值(包含public、private、protected)
3、获取method方法的方式
(1)获取运行时类及其父类中声明为public的的方法
(2)获取运行时类本身的所有声明的方法
·获取方法中的权限修饰符、返回值类型、方法名、形参列表
(3)获取指定方法,并且对指定的方法进行相应的赋值并运行(包含public、private、protected)
4、获取类的构造器
(1)获取类的所有构造器
(2)获取类的指定构造器

1、三种常用方式和使用类加载器获取获取Class类实例

/*
	 * java.lang.Class:是反射的源头。
	 * 我们创建了一个类,通过编译生成对应的.class文件,之后我们加载(JVM的类加载器)此.class文件。
	 * 此.class文件加载到内存以后就是一个运行时类(存放在缓存区)。那么这个运行时类本身就是一个大的Class实例。
	 * 1、每一个运行时类只加载一次。
	 * 2、有了Class类的实例以后:(1)可以创建对应的运行类的对象(2)可以获取对应的运行时类的完整结构(属性、方法、构造器、父类、所在的包、异常、注解、内部类)
	 * (3)调用对应的运行时类指定的结构(属性、方法、构造器)
	 * (4)动态代理:反射的应用
	 */

@Test
	public void test1() throws ClassNotFoundException{
		
		//获取运行时类的class属性
		Class<Person> clazz1 = Person.class;
		System.out.println(clazz1.getName());
		
		//通过运行时类的对象获取
		Person person = new Person();
		Class<Person> clazz2 = (Class<Person>) person.getClass();
		System.out.println(clazz2.getName());
		
		//通过Class类的静态方法:forName()
		Class clazz3 = Class.forName("cn.zyy.testReflect.Person");
		System.out.println(clazz3.getName());
		
		//通过类的加载器
		ClassLoader classLoader = this.getClass().getClassLoader();
		Class clazz4 = classLoader.loadClass("cn.zyy.testReflect.Person");
		System.out.println(clazz4.getName());
	}

2、获取field属性的方式

@Test
	public void test2() throws NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException{
		
		//1、获取运行时类及其父类中声明为public的的属性
		Class clazz = Person.class;
		Field[] fields_public = clazz.getFields();
		for(Field field : fields_public){
			System.out.println(field.getName());
		}
		
		//2、获取运行时类本身的所有声明的属性
		Field[] fields_own = clazz.getDeclaredFields();
		System.out.println("获取运行时类本身的所有声明的属性==开始");
		for(Field field : fields_own){
			//获取类的属性类型、属性名称、权限修饰符
			int ii = field.getModifiers();
			String modifier = Modifier.toString(ii);
			System.out.println("类的"+field.getName()+"属性的权限修饰符是:"+modifier);
			Class fieldTypeClass = field.getType();
			String fieldType = fieldTypeClass.getName();
			System.out.println("类的"+field.getName()+"属性的类型是:"+fieldType);
		}
		System.out.println("获取运行时类本身的所有声明的属性==结束");
		
		//3、获取指定属性,并且对指定的属性进行相应的赋值(包含public、private、protected)
		Object obj = clazz.newInstance();
		Person person = (Person) obj;
		//private属性
		Field field_name = clazz.getDeclaredField("name");
		field_name.setAccessible(true);
		field_name.set(person, "张哈哈");
		System.out.println(field_name.get(person));
		//public属性
		Field field_address = clazz.getDeclaredField("address");
		field_address.set(person, "beijing");
		System.out.println(field_address.get(person));
		//protected属性
		Field field_id = clazz.getDeclaredField("id");
		field_id.set(person, 12);
		System.out.println(field_id.get(person));
	}

3、获取method方法的方式

@Test
	public void test3() throws Exception{
		
		//1、获取运行时类及其父类中声明为public的的方法
		Class clazz = Person.class;
		Method[] methods_public = clazz.getMethods();
		for(Method method : methods_public){
			System.out.println(method.getName());
		}
		//2、获取运行时类本身的所有声明的方法
		Method[] methods_own = clazz.getDeclaredMethods();
		for(Method method : methods_own){
			//获取方法中的权限修饰符、返回值类型、方法名、形参列表
			int ii = method.getModifiers();
			String modifier = Modifier.toString(ii);
			System.out.println("类的"+method.getName()+"方法的权限修饰符是:"+modifier);
			Class<?> returnTypeClass = method.getReturnType();
			String returnType = returnTypeClass.getName();
			System.out.println("类的"+method.getName()+"方法的返回值类型是:"+returnType);
			Class [] parameters = method.getParameterTypes();
		}
		
		//3、获取指定方法,并且对指定的方法进行相应的赋值并运行(包含public、private、protected)
		Person person = (Person) clazz.newInstance();
		//private方法(注意要使用getDeclaredMethod,如果使用getMethod,那么会出现找不到method的情况)
		Method method_getNameById = clazz.getDeclaredMethod("getNameById", Integer.class);
		method_getNameById.setAccessible(true);
		method_getNameById.invoke(person, 12);
		//public
		Method method_getInfo = clazz.getDeclaredMethod("getInfo", String.class);
		Object returnValue = method_getInfo.invoke(person, "haha");
		System.out.println(returnValue);
	}

4、获取类的构造器

@Test
	public void test4() throws Exception{
		Class clazz = Person.class;
		//1、获取类的所有构造器
		Constructor [] constructors_public = clazz.getConstructors();
		System.out.println("获取所有public Constructor 开始");
		for(Constructor constructor : constructors_public){
			System.out.println(constructor.getName());
		}
		System.out.println("获取所有public Constructor 结束");
		
		Constructor [] constructors_own = clazz.getDeclaredConstructors();
		System.out.println("获取所有own Constructor 开始");
		for(Constructor constructor : constructors_own){
			System.out.println(constructor.getName());
		}
		System.out.println("获取所有own Constructor 结束");
		
		//2、获取类的指定构造器
		Constructor constructor = clazz.getConstructor(String.class,int.class,String.class);
		Person person = (Person) constructor.newInstance("zhangyy",12,"zhongguo");
		System.out.println(person.getAddress());
	}

例子中使用的示例类Person类:

public class Person {

	private String name;
	
	protected int id;
	
	public String address;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	public int getInfo(String name){
		if("haha".equals(name)){
			return 1;
		}else {
			return 0;
		}
	}
	
	@SuppressWarnings("unused")
	private void getNameById(Integer id){
		System.out.println(id);
	}
	
	@Override
	public String toString() {
		return "Person [name=" + name + ", id=" + id + ", address=" + address
				+ "]";
	}

	public Person(String name, int id, String address) {
		super();
		this.name = name;
		this.id = id;
		this.address = address;
	}

	public Person() {
		super();
	}
	
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值