反射-2(实操代码)

一:Other

获取运行时类的父类

public void test1() {
		Class<Person> clazz = Person.class;
		Class<? super Person> superClass = clazz.getSuperclass();
		System.out.println(superClass);
	}

通过反射获取并运行配置文件

public void test2() throws Exception {
		// 获取配置文件的对象
		Properties properties = new Properties();
		// 获取输入流(读取配置文件 将配置文件以流的形式读取)
		FileReader in = new FileReader(new File("properties"));
		// 将流加载到配置文件对象中
		properties.load(in);
		// 释放资源
		in.close();
		
		
		// 获取用户名和密码
		String uesrName = properties.getProperty("user");
		String password = properties.getProperty("password");
		System.out.println("用户名:"+uesrName+" 密码"+password);
		
		
		// 通过反射获取Class对象
		Class<?> clazz = Class.forName(properties.getProperty("className"));
		// 获取show()方法
		Method method = clazz.getMethod(properties.getProperty("methodName"));
		// 调用show方法
		// method.invoke(clazz.getConstructor().newInstance()); 
		Student student = (Student) clazz.newInstance();
		method.invoke(student);
		
	}

泛型删除:程序编译后产生的字节码文件(.class)是没有泛型约束的,这种现象称为泛型的擦除。

public void test3() throws Exception {
		ArrayList<Integer> arr = new ArrayList<Integer>();
		arr.add(123);
		// 获取ArrayList字节码对象
		Class<? extends ArrayList> c = arr.getClass();
		// 通过反射的方式获得add()方法
		Method m = c.getMethod("add", Object.class);
		// 调用方法
		m.invoke(arr, "abc");
		System.out.println(arr);
	}

二.Method

获取运行时类中指定的方法

public void test1() {
		Class clazz = Person.class;
		// 1.getMethods():获取运行时类及其父类中声明为Public的方法
		Method[] m1 = clazz.getMethods();
		for (Method m : m1) {
			System.out.println(m);
		}
		System.out.println("------------------------");
		// 2.getDeclaredMethods():获取运行时类本身声明的所有方法
		Method[] m2 = clazz.getDeclaredMethods();
		for (Method method : m2) {
			System.out.println(method);
		}
	}

调用运行时类中指定的方法

public void test2() throws Exception {
		// 创建运行时类的对象
		Class<Person> clazz = Person.class;
		Person p = (Person) clazz.newInstance();
		// 获取属性
		Field f_name = clazz.getDeclaredField("name");
		Field f_age = clazz.getDeclaredField("age");
		// 允许访问
		f_name.setAccessible(true);
		f_age.setAccessible(true);
		// 设置属性值
		f_name.set(p, "tina");
		f_age.set(p, 30);
		
		// 1.获取运行时类声明为public的方法
		Method m1 = clazz.getMethod("show");
		// 调用方法  invoke(指定对象,方法参数)
		m1.invoke(p);
		// 2.调用有返回值的方法
		Method m2 = clazz.getMethod("sayHello");
		// 调用方法并接受返回值
		Object returnVal1 = m2.invoke(p);
		System.out.println(returnVal1);
		// 3.调用静态方法
		Method m3 = clazz.getMethod("info");
		// 相当于   类名.方法名
		m3.invoke(Person.class);
		// 4.调用带参数的方法
		// 获取运行时类中所有的方法 getDeclaredMethod()
		Method m4 = clazz.getDeclaredMethod("display", String.class);
		m4.invoke(p, "china");
		
	}

调用有参数的构造器 创建运行时类的对象 调用相关的方法

public void test3() throws Exception {
		Class<Person> clazz = Person.class;
		// 得到有参数的构造器
		Constructor<Person> cons = clazz.getConstructor(String.class,int.class);
		// 通过有参的构造器创建运行时类的实例(初始化成员属性)
		Person p = cons.newInstance("tom",25);
		System.out.println(p);
		// 获取方法
		Method method = clazz.getMethod("display",String.class);
		// 调用方法
		method.invoke(p, "USA");
		
				
	}

三:Field

1.getFields():获取运行时类及其父类中声明的为public类型的属性
2.getDeclareFields():获取运行时类本身声明的所有属性

public void test1() {
		Class clazz = Person.class;
		// 1.getFields():获取运行时类及其父类中声明的为public类型的属性
		Field[] fields = clazz.getFields();
		for (Field field : fields) {
			System.out.println(field);
		}
		// 2.getDeclareFields():获取运行时类本身声明的所有属性
		Field[] fields2 = clazz.getDeclaredFields();
		for (Field field : fields2) {
			// 获取属性名称
			System.out.println(field.getName());
		}
	}

获取属性的各个部分内容(权限修饰符、类型、名称)

public void test2() {
		Class clazz = Person.class;
		Field[] fields = clazz.getDeclaredFields();
		for (Field f : fields) {
			// 1.获取每个属性的访问修饰符
			int modifiers = f.getModifiers();
			// Modeifier.toString(int num):将num对应的数值转换为对应的访问修饰符   1 - public 2 - private
			System.out.println(Modifier.toString(modifiers));
			// 获取属性的类型
			Class<?> type = f.getType();
			String typeName = type.getName();
			System.out.println(typeName);
			// 3.获取属性名称
			System.out.println(f.getName());
		}
	}

获取运行时类指定的属性

public void test3() throws Exception {
		Class clazz = Class.forName("com.hpe.reflect.Person");
		// 1.获取指定的属性
		// getField(String name):获取运行时类中声明为public指定属性名的属性
		Field name = clazz.getField("name");
		// 2.创建运行时类的对象
		Person p = (Person) clazz.newInstance();
		System.out.println(p);
		// 3.设置属性值
		name.set(p, "ecic");
		System.out.println(p);
		// 4.getDeclareField(Sting filedName):获取运行时类指定的属性名
		Field age = clazz.getDeclaredField("age");
		
		// 由于属性权限修饰符的限制,为了保证给属性赋值,需要在操作前使得该属性可被操作
		age.setAccessible(true);
		
		age.set(p, 15);
		System.out.println(p);
		
	}

四:构造器

方法与上方类似

发布了30 篇原创文章 · 获赞 0 · 访问量 1936

猜你喜欢

转载自blog.csdn.net/qq_38499019/article/details/104758086