反射

首先是类的加载,连接,初始化

四种获取类的Class对象的方法

1、类型名.class说明:

基本数据类型和void,只能通过这种方式。

2、对象.getClass():获取对象的运行时类型说明:只能用于引用数据类型

3、Class.forName(“类的全名称")类的全名称:包.类名

4、类加载器对象.loadClass(“类的全名称")

然后是四种类加载器

1、引导类加载器(Bootstrap Classloader):又称为根类加载器它负责加载]ava的核心库

它用原生代码(C/C++)来实现的,并不继承自java.lang.ClassLoder

2、扩展类加载器(Extension ClassLoader) JAVA_HOME/ire/ext/*.jar

3、应用程序类加载器(Application Classloader) classpath下,就是自定义类型

4、自定义类加载器例如:tomcat

Java的类加载的过程是一个双亲(parent)委托模式加载的:

当“应用程序类加载器”接到一个加载任务时:

(1)先搜索内存中是否已经加载过了,如果加载过了,就可以找到对应的Class对象,那么就不加载了。

(2)如果没有找到,把这个任务先提交给“parent”,父加载器接到任务时,也是重复(1)(2)

(3)直到传给了根加载器,如果根加载器可以加载,就完成了,如果不能加载,往回传,依次每个加载器尝试在自己负责的路径下搜索,如果找到就直接返回C1ass对象,如果一直回传到“应用程序类加载器”,还是没有找到,就会报ClassNotFoundException。

反射_第1张图片

类加载器的作用:

1、最主要的作用:加载类

2、辅助的作用:可以用它来加载“类路径下”的资源文件

JavaSE:例如:bin中SrC下文件-->bin目录下

ClassLoader:

(1)静态方法

ClassLoader.getSystemResourceAsStream("src1.properties")

但是这个适用于JavaSE阶段,因为它用应用程序类加载器去加载的如果是Web阶段,用这个方法是有问题的,因为web阶段的类路径在WEB-INF/classes下,必须由它自定义类加载器

(2)非静态方法

类加载器对象.getResourceAsStream("src1.properties") Web阶段用这个

Properties:Properties类表示了一个持久的属性集。Properties可保存在流中或从流中加载。属性列表中每个键及其对应值都是字符串

通过反射查看类的信息

在运行期间,动态的获取某个类的详细信息步骤:

1、获取某个类型的Class对象

2、使用Class和java.lang.reflect包下面的其他类型的API

使用反射生成并操作对象

在运行期间,动态的创建任意类型的对象,

1、Class对象.newInstance()

前提:这个类型必须有无参构造

步骤:

(1)获取Class对象

(2)直接调用Class对象.newInstance()

2、构造器来创建对象

步骤:

(1)获取Class对象

(2)获取构造器对象,获取其中一个

C1ass类中有这样的方法:

Constructor getDeclaredConstructor(Class<?>..…parameterTypes)

parameterTypes:构造器形参的类型列表

(3)用构造器创建对到 java.lang.reflect.Constructor类型中:

T newInstance(Object...initargs)

initargs:创建对象时,给构造器的实参列表

运行期间,动态的为对象的属性赋值或获取属性值步骤:

1、获取Class对象

2、获取Field属性对象

3、创建实例对象,Class代表的类型的实例对象

4、调用Fie1d对象.set(实例对象,属性值)调用Field对象.get(实例对象)

说明:如果属性是私有的,那么可以调用Field对象.setAccessible(true);

在运行期间,动态的调用任意对象的任意方法步骤:

1、获取Class对象

2、获取Method对象

方法有重载,就用方法名+形参列表clazz.getDeclaredMethod(name,parameterTypes)

3、创建实例对象

4、调用方法

public static Object createobject() {

   	try {
   		// 创建properties集合
   		Properties pro = new Properties();
   		// 从文件中加载内容到集合中
   		pro.load(BeanDemo.class.getResourceAsStream("/stu.properties"));
   		// 从集合中获得类名
   		String className = pro.getProperty("class");
   		// 通过反射获得Class对象
   		Class c = Class.forName(className);
   		// 快速创建对象
   		Object obj = c.newInstance();
   		// 遍历集合
   		Set names = pro.stringPropertyNames();
   		for (String name : names) {
   			// 判断name是否class
   			if (name.equals("class"))
   				continue;
   			// 获得值
   			String value = pro.getProperty(name);
   			// name:成员变量名
   			// 根据成员变量名获得对应的Field对象
   			Field f = c.getDeclaredField(name);
   			// 强制反射
   			f.setAccessible(true);
   			// 获得成员变量的类型
   			Class typeclass = f.getType();
   			if (typeclass == int.class) {// 判断成员变量的数据类型是否是int类型
   				f.setInt(obj, Integer.parseInt(value));

   			} else {
   				// 给对象的赋值
   				f.set(obj, value);

   			}
   		}
   		// 返回对象
   		return obj;
   	} catch (Exception e) {
   		throw new RuntimeException(e);
   	}

   }

你可能感兴趣的:(反射)