黑马程序员-java中的反射总结

------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------

Java 反射总结

类装载器工作机制

类装载器就是寻找类的节码文件并构造出类在JVM 内部表示对象的组件。在Java 中, 
类装载器把一个类装入JVM 中,要经过以下步骤: 
1.装载:查找和导入Class 文件; 
通过一个类的全限定名来获取定义此类的二进制字节流.然后将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构.最后在Java堆中生成一个代表这个类的java.lang.class对像,作为方法区的数据入口.

2.链接:执行校验、准备和解析步骤,其中解析步骤是可以选择的: 
a)校验:检查载入Class 文件数据的正确性; 
b)准备:给类的静态变量分配存储空间; 
c)解析:将符号引用转成直接引用;

3.初始化:对类的静态变量、静态代码块执行初始化工作。

类装载工作由ClassLoader 及其子类负责,ClassLoader 是一个重要的Java 运行时系统组件,它负责在运行时查找和装入Class 字节码文件。JVM 在运行时会产生三个 
ClassLoader: 
BootstrapClassLoader 
Extension ClassLoader(扩展类装载器) 
Application ClassLoader(系统类装载器)。

其中,BootstrapClassLoader不是ClassLoader 的子类,它使用C++编写,因此我们在Java 中看不到它,BootstrapClassLoader负责装载JRE 的核心类库,如JRE 目标下的rt.jar、charsets.jar 等。

Extension ClassLoader 和Application ClassLoader 都是ClassLoader 的子类。其中Extension ClassLoader 负责装载 JRE 扩展目录ext 中的JAR 类包;Application 负责装载Classpath 路径下的类包。

getParent() 返回该类加载器的父类加载器。
loadClass(String name) 加载名称为 name 的类,返回的结果是 java.lang.Class 类的实例。
findClass(String name)  查找名称为 name 的类,返回的结果是 java.lang.Class 类的实例。
findLoadedClass(String name)  查找名称为 name 的已经被加载过的类,返回的结果是 java.lang.Class 类的实例。
defineClass(String name, byte[] b, int off, int len) 把字节数组 b 中的内容转换成 Java 类,返回的结果是 java.lang.Class 类的实例。这个方法被声明为 final 的。
resolveClass(Class<?> c) 链接指定的 Java 类。

?


1

2

3

4

5

6

7

8

public class ClassLoaderTest { 

public static void main(String[] args) { 

ClassLoader loader = Thread.currentThread().getContextClassLoader(); 

System.out.println("current loader:"+loader); 

System.out.println("parent loader:"+loader.getParent()); 

System.out.println("grandparent loader:"+loader.getParent(). getParent()); 

}

?


1

2

3

4

current loader:sun.misc.Launcher$AppClassLoader@131f71a

parent loader:sun.misc.Launcher$ExtClassLoader@15601ea

//①根装载器在Java中访问不到,所以返回null 

grandparent loader:null

通过以上的输出信息,我们知道当前的ClassLoader 是AppClassLoader,父ClassLoader是ExtClassLoader,祖父ClassLoader 是根类装载器,因为在Java 中无法获得它的句柄,所以仅返回null。

JVM 装载类时使用“全盘负责委托机制”,“全盘负责”是指当一个ClassLoader 装载一个类的时,除非显式地使用另一个ClassLoader,该类所依赖及引用的类也由这个ClassLoader 载入;“委托机制”是指先委托父装载器寻找目标类,只有在找不到的情况下才从自己的类路径中查找并装载目标类。这一点是从安全角度考虑的,试想如果有人编写了一个恶意的基础(如java.lang.String)并装载到JVM 中将会引起多么可怕的后果。但是由于有了“全盘负责委托机制”,java.lang.String 永远是由根装载器来装载的,这样就避免了上述事件的发生。

获取当前线程的ClassLoader:

?


1

2

ClassLoader loader = Thread.currentThread().getContextClassLoader();

Class.getClassLoader() ;

实例化Class类对象的三种方式:

?


1

2

3

Class.forName("Reflect.Demo");

new Demo().getClass();

Demo.class;

Class.forName(className)实际上是调用Class.forName(className, true, this.getClass().getClassLoader())。注意第二个参数,是指Class被loading后是不是必须被初始化。

通过Class实例化其他类的对象

?


1

2

3

Class<?>  demo=Class.forName("Reflect.Person");

Constructor<?> cons[]=demo.getConstructors();

Object object = cons[0].newInstance(args);

通过Class实例化接口

?


1

Class<?> intes[]=demo.getInterfaces();

取得其他类中的父类

?


1

Class<?> superClass=demo.getSuperclass();

调用其他类中的方法

?


1

2

3

4

5

6

demo = Class.forName("Reflect.Demo");

Method method=demo.getMethod("toString");

method.invoke(demo.newInstance());

Method[] methods = demo.getDeclaredMethods();

通过反射操作属性:

?


1

2

3

4

5

6

7

Field field = demo.getDeclaredField("sex");

field.setAccessible(true);

field.set(obj, "男");

Field[] fields = Demo.class.getDeclaredFields(); //类中任何可见性的属性不包括基类

fields = Demo.class.getFields();  //只能获得public属性包括基类的

使用数组

?


1

2

3

4

Class string = Class.forName("java.lang.String"); 

Object object= Array.newInstance(string, 10); 

Array.set(object, 5, "this is a test"); 

 String s = (String) Array.get(arr, 5);

=============================应用========================== 
JDK动态代理: 
与静态代理类对照的是动态代理类,动态代理类的字节码在程序运行时由Java反射机制动态生成,无需程序员手工编写它的源代码。动态代理类不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java 反射机制可以生成任意类型的动态代理类。java.lang.reflect 包中的Proxy类和InvocationHandler 接口提供了生成动态代理类的能力。

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

public class MyHandler implements InvocationHandler {  

    private Object target;  

       

    public Object bind(Object target) {  

        this.target = target;   

        return Proxy.newProxyInstance(target.getClass().getClassLoader(),  

                target.getClass().getInterfaces(), this);  

    }   

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {  

        System.out.println("事物开始");   

        Object result = method.invoke(target, args);  

        System.out.println("事物结束");  

        return result;  

    }    

   

}

Cglib动态代理  
JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

public class MyCglib implements MethodInterceptor {  

    private Object target;  

    

    public Object getInstance(Object target) {  

        this.target = target;  

        Enhancer enhancer = new Enhancer();  

        enhancer.setSuperclass(this.target.getClass());  

        // 回调方法  

        enhancer.setCallback(this);  

        // 创建代理对象  

        return enhancer.create();  

    }  

    @Override

    // 回调方法  

    public Object intercept(Object obj, Method method, Object[] args,  

            MethodProxy proxy) throws Throwable {  

        System.out.println("事物开始");  

        proxy.invokeSuper(obj, args);  

        System.out.println("事物结束");  

        return null;  

    }  

}

时间: 2024-10-25 14:48:08

黑马程序员-java中的反射总结的相关文章

黑马程序员--Java中的反射逻辑

------- <a href="http://www.itheima.com" target="blank">android培训</a>.<a href="http://www.itheima.com" target="blank">java培训</a>.期待与您交流! ---------- 1 .      反射是在运行状态中,对于任意一个类(class文件),都能够知道这个

黑马程序员-Java基础之反射

反射 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制. Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类:在运行时构造任意一个类的对象:在运行时判断任意一个类所具有的成员变量和方法:在运行时调用任意一个对象的方法:生成动态代理. 反射说白了就是可以获得一个类的所有信息,主要包括方法和属性两部分.1.获得方法包括获得方

黑马程序员----Java高新技术之反射学习总结

------- android培训.java培训.期待与您交流! ---------- 反射的概念. 1.Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类中的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制. 精妙的总结就是:反射就是将Java类中的各个成分映射成相应的Java类. 3.在Java中,描述事物的各种类同样也是一种事物,也可以用面向对象的方法来描述,即也有一个类来描述众多的J

黑马程序员------Java中多线程学习总结(一)

Java培训.Android培训.iOS培训..Net培训</a>.期待与您交流! 一.多线程的概念 进程:是一种“自包容”的运行程序,有自己的地址空间. 基于进程的特点是允许计算机同时运行两个或更多的程序 线程:是进程内部单一的一个顺序控制流 . 基于线程的多任务处理环境中,线程是最小的处理单位. 在Java中,一个应用程序可以包含多个线程.每个线程执行特定的任务,并可与其他线程并发执行.多线程使系统的空转时间减少,提高了CPU的利用率.多线程编程隐藏了CPU在任务之间切换的事实. 二.创建

黑马程序员------Java中jdk1.5新特性

Java培训.Android培训.iOS培训..Net培训.期待与您交流! JDK1.5新特性: 为什么会出现新特性: 新的技术出现是为了解决老的问题,Java语言为了提高开发者的开发效率,对之前的某些不利于提高效率的技术进行改进. 静态导入: 静态导入:可以导入某个类下的静态方法,静态导入后,可以不写类名而直接使用此类下的静态方法. 语法:import static 包名.类名.静态方法 代码示例: package com.itheima.day1; /** * 静态导入 * @author

黑马程序员————java中的网络编程

------<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS培训..Net培训</a>.期待与您交流! ------- java中的网络编程 一.网络编程概述:基于互联网的编程 就是用来实现网络互连的不同计算机上运行的程序间可以进行数据交换. 二.网络模型:OSI和TCP/IP 1.OSI(Open System Interconnection开放系统互连

黑马程序员------Java中GUI(图形用户界面)学习总结

Java培训.Android培训.iOS培训..Net培训</a>.期待与您交流! GUI: Graphical User Interface(图形用户接口). 即用图形的方式,来显示计算机操作的界面,以方便用户更容易更直观地操作. Java中为GUI提供的对象都在Java.Awt和Javax.Swing两个包中. java.Awt: Abstract Window ToolKit (抽象窗口工具包). 需要调用本地系统方法实现功能,属于重量级控件. javax.Swing: 在AWT的基础上

黑马程序员-Java中的基本数据类型

------<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS培训..Net培训</a>.期待与您交流! ------- Java中的数据类型分为两个大类:基本数据类型和引用数据类型. 其中基本数据类型又可以分为四类:整型数据类型,小数数据类型,字符类型,布尔型. 整型数据类型还分为:byte,short,int(整型),long(长整型).默认为int型.

黑马程序员————java中的抽象类

------<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS培训..Net培训</a>.期待与您交流! ------- 抽象类集中的体现了java面向对象的特性,对于每一种事物通过五个方面:属性,方法,构造器,代码块,内部类,来重新解构再进行组装,然后将类似的事物归为一类,这是面向对象的思想.java中常说万物皆对象,那么很显然我们可以进一步的将其中的方法