反射

java反射机制
java反射机制是一种动态机制,它允许我们加载一个类实例化一个类,调用方法或操作属性从编码期间确定转为在运行期间确定。
这样做可以大大提高代码的灵活度,但是反射有更大的资源开销。所以不能过度依赖反射。

Class 用来描述类本身

Class类
Class类的每一个实例用于表示JVM已经加载的一个类。并且在JVM内部每个被加载的类都有且只有一个Class的实例与之对应。通过类对象我们可以:
获取其表示的类的名字,构造方法,方法,属性,并可以快速实例化。

获取一个类的类对象有以下方式:
1:直接通过类的静态属性class得到。
比如像获取String的类对象,我们可以:
Class cls = Person.class;

2:通过Class的静态方法forName加载:
Class cls = Class.forName(“java.lang.String”);

3:通过类加载器ClassLoader
对象.getClass();

Package 类中的包

Field 用来描述类中的属性

Method 描述类中的方法

Constructor 类的构造方法

Annotation 类中的注解

public static void main(String[] args) {
		try {
			//获得类的三种方法
			System.out.println(Class.forName("atm.Test$Person"));
			System.out.println(Person.class);
			System.out.println(new Test().new Person().getClass());
			
			Class clazz1 = Class.forName("atm.Test$Person");
			System.out.println("类的修饰符"+clazz1.getModifiers());;
			Class clazz = Class.forName("java.util.ArrayList");
			System.out.println(clazz);
			System.out.println(ArrayList.class);
			System.out.println(new ArrayList<String>().getClass());
			
			System.out.println("类的修饰符"+clazz.getModifiers());
			System.out.println("类的名字有包"+clazz.getName());
			System.out.println("类的名字"+clazz.getSimpleName());
			
			Package package1 = clazz.getPackage();
			System.out.println("类所在的包"+package1.getName());
			
			Class class1 = clazz.getSuperclass();
			System.out.println("父类"+class1);
			
			Class[] classes = clazz.getInterfaces();	
			for (Class class2 : classes) {
				System.out.println("实现的接口"+class2);
			}
			
			//相当于调用无参数构造方法创建对象,如果没有无参数构造方法,会抛出异常
			Object object = clazz.newInstance();
			
			//获取类的属性,只能看到public修饰的
			Class class3 = Atm.class;
			Atm atm = (Atm) class3.newInstance();
			Field field = class3.getField("size");
			//属性的修饰符
			System.out.println(field.getModifiers());
			//属性的类型
			System.out.println(field.getType());
			//属性的名字
			System.out.println(field.getName());
			//给属性赋值
			field.set(atm, "张三");
			//取出属性的值
			System.out.println(field.get(atm));
			//获取类中的所有属性,自己的和父类的所有public的
			Field[] fields = class3.getFields();
			for (Field field2 : fields) {
				System.out.println(field2);
			}
			//获得其他权限修饰符的属性
			Field field1 = class3.getDeclaredField("age");
			//修改属性被操作的状态(允许私有属性被赋)
			field1.setAccessible(true);
			field1.set(atm, 1);
			System.out.println(field1.get(atm));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
public static void main(String[] args) {
		//通过反射修改String的不可变特性
		try {
			String string = "李四";
			Class clazz1 = String.class;
			Field value = clazz1.getDeclaredField("value");
			value.setAccessible(true);
			//获取value的内存地址
			char[] cs = (char[])value.get(string);
			cs[0]='张';
			cs[1]='三';
			System.out.println(string);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

获取类中的方法

public static void main(String[] args) {
		Class clazz = Atm.class;
		//获取类中的所有方法
		//获取自己类和父类的所有public方法
		Method[] methods =	clazz.getMethods();
		System.out.println(methods);
		try {
			//根据方法名字获得类中的一个方法
			//根据名字获取自己类和父类的所有public方法
			Method method = clazz.getMethod("eat");
			//........
			int a = method.getModifiers();
			Class b = method.getReturnType();
			String c = method.getName();
			Class[] d = method.getParameterTypes();
			Class[] e = method.getExceptionTypes();
			//调用方发执行
			method.invoke(clazz.newInstance());
			//获得有参数的方法并执行
			Method method2 = clazz.getMethod("eat", int.class,String.class);
			Object object = method2.invoke(clazz.newInstance(), 10,"张三");
			System.out.println((Integer)object);
			
			//获得其他修饰符的方法
			Method method3 = clazz.getDeclaredMethod("slep");
			//此时不能直接赋值,需要设置方法的准入权
			method3.setAccessible(true);
			method3.invoke(clazz.newInstance());
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}

获取类中的构造方法

public static void main(String[] args) {
		try {
			Class clazz = Atm.class;
			clazz.getConstructors();
			Constructor cons = clazz.getConstructor();
			//执行构造方法
			cons.newInstance();
			Constructor cons1 = clazz.getConstructor(String.class,Integer.class);
			cons1.newInstance("张三",111);	
		} catch (Exception e) {
			e.printStackTrace();
		}

	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值