——Java中反射机制09

原创 2015年07月11日 08:34:20


一、类的加载:

原理理解:

当使用某个类的时候,如果该类还没有被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化。

a、

加载:

就是指将class文件读入到内存,并创建一个Class对象

         任何类被使用时系统都会建立一个Class对象

b、

连接:

          验证 : 是否有正确的内部结果,并和其他类协调一致。

         准备: 负责为类的静态成员分配内存,并配置默认初始化值。

         解析: 将类的二进制数据中的符号引用替换为直接的引用。

c、

初始化

类初始化时机:

1.访问类的实例

2.访问类的静态变量,或者为静态变量赋值,

3.调用类的静态方法

4.调用反射方式来强制创建某个类或者接口对应的

5. Java.lang.Class对象。

6. 初始化某个类的子类

7. 直接使用java.exe命令来运行某个主类。


二、类加载器:

将.class文件加载到内存中,并生成对应的Class对象

分为三种:

BootstrapClassLoader 根类加载器:

(引导类加载器)负责java核心类加载,

如System,String等,在JDK中JRE的lib目录下rt.jar文件中


Extension ClassLoader扩展类加载器:

 负责JRE的扩展目录中Jar包的加载

在JDK中JRE的lib目录下ext目录


SystemClassLoader  系统类加载器:

负责在JVM启动时加载来自java命令的class文件

以及classpath环境变量所指定的jar包和类路径


三、什么是反射? 

1、原理理解:

能够知道任意一个类的所有属性和方法,且能调用它的任意一个方法和属性,

这种动态获取的信息以及动态调用对象的方法的功能称为java语音的反射机制。

要解剖一个类,首先要获取到类的每一个字节码文件对应的Class类型的对象,

其中用的是Class类中的方法:

成员变量 Field

构造方法 Constructor

成员方法  Method


2、获取class文件对象的方式:

三种方式:

a.

Person  p  =  new Person();

Class  c1  =  p.getClass();


b.

Class  c2  =  Person.class; 


c.

Class  c3  =  Class.forName(“myReflect.Person”);

PS.

c1  ==  c2   true

c2  ==  c3   true

1和2都运用于日常(2较方便),3常用于项目开发,

3中的全路径通常通过配置文件中存储的路径,因为容易出错。



    3、Constructor

    获取构造方法:

       1)得到这个类的所有构造方法:如得到上面示例中Person类的所有构造方法

            Constructor[] cons = Class.forName(“myReflect.Person”).getConstructors();

      2)获取某一个构造方法:

           Constructor con=Person.class.getConstructor(String.class,int.class);

括号中是参数的字节码文件对象。

4、Field

获取类中一个成员变量

       FieldgetField(String s);//只能获取公有和父类中公有

     FieldgetDeclaredField(String s);//获取该类中任意成员变量,包括私有

     setAccessible(ture);

     //如果是私有字段,要先将该私有字段进行取消权限检查的能力。也称暴力访问。

  set(Objectobj, Object value);//将指定对象变量上此Field对象表示的字段设置为指定的新值。

     Object get(Objectobj);//返回指定对象上Field表示的字段的值。


5、Method

调用某个对象身上的方法,要先得到方法,再针对某个对象调用。

       Method[] getMethods();//只获取公共和父类中的方法。

        Method[] getDeclaredMethods();//获取本类中包含私有。

        Method  getMethod("方法名",参数.class(如果是空参可以写null));

        Object invoke(Objectobj ,参数);//调用方法

       如果方法是静态,invoke方法中的对象参数可以为null。


6、案例演示:

案例1:

<span style="font-size:14px;">package myDemo;

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

public class ClassDemo {

	@SuppressWarnings({ "rawtypes", "unused" })
	public static void main(String[] args) throws Exception {
		//Class c = Person.class;
		//获取字节码文件对象
		Class c = Class.forName("myDemo.Person");
		
		//获取私有构造方法对象
		//Constructor[] cons = c.getConstructors();获取所以的公共构造方法
		//Constructor[] cons = c.getDeclaredConstructors();获取所以的构造方法
		Constructor con = c.getDeclaredConstructor();
		
		//用私有构造方法创建对象
		Object obj = con.newInstance();
		
		//con.setAccessible(true);暴力访问,设置为true则指反射的对象在使用时取消java语言访问检查。
		
		//第一个参数表示方法名,第二个参数表示的是方法的参数的class类型。
		Method method = c.getMethod("method_1",String.class);
		//String s = (String)method.invoke(obj,"zzz");
		
		//调用obj的method方法,给方法参数赋值为“zzz”;
		Object objString = method.invoke(obj,"zzz");
		System.out.println(objString);
	
	}

}</span><span style="font-size:18px;">
</span>


案例2:

创建老师对象:

package myDemo;

public class Teacher {
	public void love(){
		System.out.println("爱校长。");
	}
}

创建学生对象:

package myDemo;

public class Student {
	public void love(){
		System.out.println("爱学习。");
	}
}

配置文件:


反射调用:

package myDemo;

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

public class ReflectDemo {

	public static void main(String[] args) throws  Exception {
		//读取配置文件
		FileReader fis = new FileReader("class.txt");
		
		Properties pop = new Properties();
		
		//导入配置文件信息
		pop.load(fis);
		
		//获取配置文件中的路径
		String className = pop.getProperty("className");
		String classMethod = pop.getProperty("classMethod");
		
		Class c = Class.forName(className);
		//通过配置路径获取对象的字节码对象
		
		//获取构造方法对象
		Constructor con = c.getConstructor();
		
		//用构造方法创建对象
		Object obj = con.newInstance();
		
		//获取方法LOVE
		Method m = c.getMethod("love");
		
		m.invoke(obj);//调用方法
	}

}<strong>
</strong>


当配置路径设为学生时结果为:



案例演示3:

在ArrayList<Integer> list = new ArrayList<Integer>(); 
在这个泛型为Integer的ArrayList中存放一个String类型的对象。

<span style="font-size:14px;">/**
 * 
 */
package myTestDir;

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

/**
 * @author LinP
 *第三题:ArrayList<Integer> list = new ArrayList<Integer>(); 
 *
 * 在这个泛型为Integer的ArrayList中存放一个String类型的对象。
 */
public class Test3 {

	/**
	 * @param args
	 * @throws Exception 
	 * @throws NoSuchMethodException 
	 */
	public static void main(String[] args) throws Exception {
		// 创建集合对象
		ArrayList<Integer> list = new ArrayList<Integer>(); 
		
		//获取list的字节码文件
		Class c = list.getClass();//集合ArrayLiset中的class文件对象
		
		//用Method类调用c中的Method方法。
		Method method = c.getMethod("add",Object.class);
		
		method.invoke(list, "hello");//调用list的add方法,传入的值是hello
		System.out.println(list);
	}

}</span><span style="font-size:18px;"><strong>
</strong></span>

美好的一天!



java学习笔记09--反射机制

什么是反射: 反射是java语言的一个特性,它允许程序在运行时来进行自我检查并且对内部的成员进行操作。例如它允许一个java的类获取他所有的成员变量和方法并且显示出来。 java的反射机制的实现要...

Java笔记——利用反射机制获取成员变量及成员方法

package tmp; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; im...

黑马程序员——-Java反射机制-

黑马程序员——-Java反射机制------- ---------------------- ASP.Net+Unity开发、 href="http://www.itheima.com"targe...

初识Java反射机制——Reflection(一)

在学了面向对象的语言Java之后,肯定会接触到对象的封装,类、属性、方法的修饰符public和private以及default,那接下来如果认识了java的反射机制,会更加深对类的封装的认识。...

核心java系统——反射机制

反射的简介反射是java中一种很强大的工具,能够动态分析java的类的能力,在运行状态中,对于任意一个类,通过反射都能知道这个类的属性和方法。这种动态获取的信息以及动态调用对象的方法的功能称为Java...

Java开发——反射机制

前言: 在面向对象的世界里,万事万物皆对象。但是在java语言中,静态的成员、普通数据类型除外,静态成员属于类,而不是对象,而普通数据类型有对应的包装类来弥补它。类是不是对象呢?类是(哪个类的对象呢...

java语言基础入门——反射机制实例

1、什么是反射呢?反射可以理解为在程序运行时获取对象类型信息的操作。它允许动态的发现和绑定类、方法、字段,甚至由其他语言产生的元素。运用反射可以做到列举对象所对应的类的详细信息,如访问修饰符,包名,类...

黑马程序员——java学习笔记--反射机制

什么是反射: 反射是java语言的一个特性,它允许程序在运行时来进行自我检查并且对内部的成员进行操作。例如它允许一个java的类获取他所有的成员变量和方法并且显示出来。 java的反射机制的实现要借...

java基础学习笔记——反射机制

Java反射机制相关知识。
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:——Java中反射机制09
举报原因:
原因补充:

(最多只允许输入30个字)