java 动态性之反射机制reflection

 

反射机制

– 指的是可以于运行时加载、探知、使用编译期间完全未知的类。 – 程序在运行状态中,可以动态加载一个只有名称的类,对于任意一个 已加载的类,都能够知道这个类的所有属性和方法;对于任意一个对 象,都能够调用它的任意一个方法和属性;

Class c = Class.forName("com.bjsxt.test.User");

– 加载完类之后,在堆内存中,就产生了一个 Class 类型的对象(一个 类只有一个 Class 对象),这个对象就包含了完整的类的结构信息。 我们可以通过这个对象看到类的结构。这个对象就像一面镜子,透过 这个镜子看到类的结构,所以,我们形象的称之为:反射。

Class介绍

java.lang.Class类十分特殊,用来表示java中类型 (class/interface/enum/annotation/primitive type/void)本 身。

    – Class类的对象包含了某个被加载类的结构。一个被加载的类对应一个 Class对象。

    – 当一个class被加载,或当加载器(class loader)的defineClass()被 JVM调用,JVM 便自动产生一个Class 对象。

• Class类是Reflection的根源。 – 针对任何您想动态加载、运行的类,唯有先获得相应的Class 对象

测试

student类

package bean;

public class User {
	private String name;
	private int age;
	private int id;
	public User(String name, int age, int id) {
		super();
		this.name = name;
		this.age = age;
		this.id = id;
	}
	
	public User() {
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	
	
}
package test;

@SuppressWarnings("all")
public class Demo1 {
	public static void main(String[] args) throws ClassNotFoundException {
		String path = "bean.User";//类的路径
		//对象是表示或封装一些数据,一个类被加载后,JVM会创建一个对应类的Class对象,类的整个结构信息会放到对应的Class对象中
		//这个对象就像一面镜子,通过这个镜子可以看到对应类的所有信息,就像图纸一样
		Class<?> clz1 = Class.forName(path);
		System.out.println(clz1.hashCode());
		
		Class<?> clz2 = Class.forName(path);
		System.out.println(clz2.hashCode());//同一个类hashcode一致,既同一个类就会被加载一次
		
		//获得String类Class对象
		Class strClaz = String.class;
		Class strClaz2 = path.getClass();
		System.out.println(strClaz == strClaz2);//都是class java.lang.String类对象
		
		//数组
		int[] arr01 = new int[10];
		int[] arr02 = new int[20];
		int[][] arr03 = new int[10][30];
		System.out.println(arr01.getClass().hashCode());
		System.out.println(arr02.getClass().hashCode());//同一维度数组的Class对象一致,与数组长度无关
 		System.out.println(arr03.getClass().hashCode());//不同维度数组的Class对象不一致

	}
}	

应用反射的api 获取类的信息(类的名字,属性,方法,构造器等)

package test;

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

/*
 * 	应用反射的api 获取类的信息(类的名字,属性,方法,构造器等)
 * 	
 * 
 */
@SuppressWarnings("all")
public class Demo02 {
	public static void main(String[] args) throws NoSuchFieldException, SecurityException, NoSuchMethodException {
		String path = "bean.User";//类的路径
		try {
			Class<?> clz = Class.forName(path);
			
			//获取类的名字
			System.out.println(clz.getName());//获取包名+类名:bean.User	
			System.out.println(clz.getSimpleName());//获取类名:User
			
			//获取属性信息
			Field[] fields = clz.getFields();//只能获得public的field
			System.out.println(fields.length);//0
			
			Field[] fields2 = clz.getDeclaredFields();//获得所有的属性
			System.out.println(fields2.length);//3
			for (Field field : fields2) {
				System.out.println(field);
			}
			/*private java.lang.String bean.User.name
			  private int bean.User.age
			  private int bean.User.id
			 */
			Field f = clz.getDeclaredField("name");
			System.out.println(f);//获取指定属性的信息:private java.lang.String bean.User.name
			
			
			//获取方法信息
			Method[] methods = clz.getDeclaredMethods();//获取所有的方法
			Method[] methods2 = clz.getMethods();//获取所有的public方法
			Method m01 = clz.getDeclaredMethod("getName", null);//第二个参数表示方法的参数,没有写null
			Method m02 = clz.getDeclaredMethod("setName", String.class);//如果有则必须指定参数的类型,方便方法的重载
			for (Method method : methods2) {
				System.out.println("方法----->" + method);
			}
			
			//获取构造器信息
			Constructor[] constructors = clz.getDeclaredConstructors();
			for (Constructor constructor : constructors) {
				System.out.println("构造器---->" + constructor);
			}
			System.out.println("获取指定的构造器---->" + clz.getConstructor(String.class,int.class,int.class));//获取无参构造器设置为null
			
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

动态操作构造器 方法 属性

package test;

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

import bean.User;
@SuppressWarnings("all")
public class Demo03 {
	public static void main(String[] args) throws Exception{
		String path = "bean.User";//类的路径
		try {
			Class clz = Class.forName(path);
			
			//利用反射api调用构造方法,构造对象
			User user = (User)clz.newInstance();//调用的是User类的无参构造器,没有会报错, 写javabean必须要无参构造器
			
			//指定构造器
			Constructor<User> c = clz.getConstructor(String.class,int.class,int.class);
			User u = c.newInstance("dan",11,222);//建立对象
			System.out.println(u.getId());//获得:222
			
			//通过反射api调用普通方法
			User u3 = (User)clz.newInstance();
			Method method = clz.getDeclaredMethod("setId", int.class);
			method.invoke(u3, 22);//相当于u3.setId(22)
			System.out.println(u3.getId());
			
			
			//通过反射api操作属性
			User u4 = (User)clz.newInstance();
			Field f = clz.getDeclaredField("name");
			f.setAccessible(true);//设置私有属性可以访问
			f.set(u4, "john");
			System.out.println(u4.getName());//这时候回报错 不能访问私有属性
			System.out.println(f.get(u4));//获取u4的f属性
			
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		
	}
}

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值