反射

1.什么是反射
是指在运行状态中,对任意一个类,都能够知道这个类的所有属性及方法;对于任意一个对象,都能调用他的任意一个属性和方法。

下面是获取class文件对象的三种方式

package cn.itcast.demo1;

public class ReflectDemo {
	public static void main(String[] args) throws ClassNotFoundException {
		//1.对象获取
		Person p = new Person();
		//调用Person父类的方法getClass,此方法也是属于Object基础类中的方法
		Class c = p.getClass();
		System.out.println(c);
		
		//2.类名获取
		//class是每个类型(基本或者引用)都会赋予的静态属性
		Class c1 = Person.class;
		System.out.println(c);
		
		//3.Class类的静态获取
		//方法forName(String className),注意类名必须是完整的路径,包括包名
		Class c2 = Class.forName("cn.itcast.demo1.Person");
		System.out.println(c2);
	}
}

Class类有很多方法,例如
(1)可以获取空参构造方法

package cn.itcast.demo1;

import java.lang.reflect.Constructor;

public class ReflectDemo1 {
	public static void main(String[] args) throws Exception {
		Class c = Class.forName("cn.itcast.demo1.Person");
		//使用文件对象获得所有公共权限的构造方法
	/*	Constructor[] cons = c.getConstructors();
		for(Constructor con : cons ){
			System.out.println(con);
		}*/
		
		//获取空参构造器
		Constructor con = c.getConstructor();
		//运行空参构造方法
		Object obj = con.newInstance();
		System.out.println(obj);
	}
}

(2)反射获取有参的构造法并赋值

package cn.itcast.demo1;

import java.lang.reflect.Constructor;

public class ReflectDemo2 {
	public static void main(String[] args) throws Exception {
		Class c = Class.forName("cn.itcast.demo1.Person");
		//获取带有参数的构造方法并运行
		//注意这里参数列表的类型要加.class
		Constructor con =c.getConstructor(String.class,int.class);
		// System.out.println(con);
		//方法newInstance,创建此 Class 对象所表示的类的一个新实例。
		Object obj = con.newInstance("张三",18);
		System.out.println(obj);
		
	}
}

(3)反射获得成员方法并运行

package cn.itcast.demo1;

//反射获得成员方法并运行
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class ReflectDemo5 {
	public static void main(String[] args) throws Exception {
		Class c = Class.forName("cn.itcast.demo1.Person");
		Object obj = c.newInstance();
		/*Method[] me = c.getMethods();
		for (Method method : me) {
			System.out.println(method);
		}*/
		
		//获取指定方法
		Method m = c.getMethod("eat");
		//调用指定的方法
		m.invoke(obj);
	}
}

这里内容比较多…感兴趣可以看看API的Class类,对后期维护好像很有帮助。

2.泛型擦除案例
定义一个泛型是String类型的集合,本来只能存储String类型,通过泛型擦除,可以实现向集合中添加其他类型元素。

package cn.itcast.demo2;

import java.lang.reflect.Method;
import java.util.ArrayList;

/*
 * 定义集合类,泛型String
 * 向集合添加Integer类型
 */
public class ReflectTest {
	public static void main(String[] args) throws Exception  {
		ArrayList<String> arr = new ArrayList<String>();
		arr.add("a");
		//反射方式调用add方法
		//获得arr的class对象
		Class c = arr.getClass();
		//通过class对象获取arr的add方法
		Method m = c.getMethod("add", Object.class);
		System.out.println(m);
		//向集合中添加Integer类型的元素,这里泛型已经被擦除
		m.invoke(arr, 5);
		System.out.println(arr);

	}
}

3.反射通过配置文件运行的步骤
(1)准备配置文件,键值对的方式
(2)IO流读取配置文件(用完记得随手关!!!)
(3)将文件中的键值对存储到集合(properties)中,集合中保存配置文件的键值对,即类名和方法
(4)反射获得指定类的class文件对象
(5)通过文件对象,获取指定的方法
配置文件:键值对的形式存储着类名及方法

className=cn.itcast.demo3.Person
methodName=eat

Person类

package cn.itcast.demo3;

public class Person {
	public void eat(){
		System.out.println("人吃饭");
	}
}

测试类

package cn.itcast.demo3;

import java.io.FileReader;
import java.lang.reflect.Method;
import java.util.Properties;

/*
 * 调用三个对象的功能
 * 类不清楚,方法也不清楚
 * 
 */
public class Test {
	public static void main(String[] args) throws Exception {
		//IO流读取配置文件
		FileReader fr = new FileReader("config.properties");
		//创建集合对象,这是存储键值对的集合
		Properties pro = new Properties();
		//从输入流中读取属性列表(键和元素对)。
		pro.load(fr);
		//关闭流释放资源
		fr.close();
		//用指定的键获取与键对应的值
		String className = pro.getProperty("className");
		System.out.println(className);
		String methodName = pro.getProperty("methodName");
		System.out.println(methodName);
		//反射获取指定类的class文件对象
		Class c = Class.forName(className);
		//创建对象的实例
		Object obj = c.newInstance();
		//获取class对象的方法 
		Method m = c.getMethod(methodName);
		//调用方法,需要对象的支持
		m.invoke(obj);
	}
}

通过这种方式,我们只需要修改键值对即可使用不同类的不同方法了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值