黑马程序员——高新技术——反射

来源:互联网 发布:后藤藤四郎极化数据 编辑:程序博客网 时间:2024/06/08 17:13
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

Day27

27.01 类的加载概述和加载时机

       1、类的加载概述

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

       加载

              就是指将class文件读入内存,并为之创建一个class对象。任何类被使用时系统都会建立一个Class对象

       连接

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

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

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

       初始化 就是我们以前讲过的初始化步骤。默认初始化,显示初始化,构造方法初始化

       2、加载时机(即加载类的几个方法)

              1创建类的实例

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

              3调用类的静态方法

              4使用反射方式来强制创建某个类或接口对应的java.lang.Class对象

              5初始化某个类的子类

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

 

27.02 类加载器的概述和分类

       1、类加载器的概述

              负责将.class文件加载到内存中,并为之生成对应的class对象。虽然我们不需要关心类加载机制,但是了解这个机制我们就能更好的理解程序的运行

       2、类加载器的分类及作用

              BootstrapClassLoader 根类加载器

                     也被称为引导类加载器,负责Java核心类的加载

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

              ExtensionClassLoader 扩展类加载器

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

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

              System ClassLoader 系统类加载器

                     负责在JVM启动时加载来自java命令的Class文件,以及classpath

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

 

27.03 反射概述

       1、反射概述

              JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法

              对于任意一个对象,都能够调用它的任意一个方法和属性

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

              要想解剖一个类,必须先要获取到该类的字节码文件对象

              而解剖使用的就是Class类中的方法,所以先要获取到每一个字节码文件对象的Class类型的对象

       2、三种方式

              Object类的 getClass方法,判断两个对象是否是同一个字节码文件

              静态属性class,锁对象

              Class类中静态方法forName,读取配置文件

       3、案例演示

if (getClass() !=obj.getClass())

//判断调用对象和传入对象的字节码文件是否是同一个字节码文件


27.04 Class.forName读取配置文件举例

       榨汁机榨汁的案例

       分别有水果、苹果、香蕉、橘子、榨汁



27.05 通过反射获取带参构造方法并使用

       Constructor

              Class类的newInstance()方法是使用该类无参的构造函数创建对象,如果一个类没有无参的构造函数,就不能创建了,可以调用Class类的getConstructor(String.class,int.class)方法获取一个指定的构造函数然后再调用Constructor类的newInstance(“张三”,20)方法创建对象


27.06 通过反射获取成员变量并使用

       String name,int age等等成员变量

       Field

              Class.getField(String)方法可以获取类中的指定字段(可见的),如果是私有的可以使用getDeclaredField(“name”)方法获取,通过set(obj,”李四”)方法可以设置指定对象上该字段的值,如果是私有的需要先调用setAccessible(true)设置访问权限,用获取的指定的字段调用get(obj)可以获取指定对象中该字段的值



27.07 通过反射获取方法并使用

       Method

              Class.getMethod(String, Class…)和Class.getDeclaredMethod(String,Class…)方法可以获取类中的指定方法,调用invoke(obj,obj…)可以调用该方法,Class.getMethod(“eat”),invoke(Object),Class.getMethdo(“eat”,int.class),invoke(obj,10)


27.08 通过反射越过泛型检查

       1、案例演示

              ArrayList<Integer>的一个对象,在这个集合中添加一个字符串数据,如何实现呢?



27.09 通过反射写一个通用的设置

设置某个对象的某个属性为指定的值

       1、案例演示

              Public voidsetProperty(Object obj ,String propertyName , Object value){}

       此方法可将Object对象中名为propertyName的属性的值设置为value




27.10 练习

已知一个类,定义如下:

       Package cn.itcast.heima;

              Public classDemoClass {

       Public void run() {

       Sop(“Welcome to heima!”);

}

}

1、写一个Properties格式的配置文件,配置类的完整名称

2、写一个程序,读取这个Properties配置文件,获得类的完整名称并加载这个类,用反射的方式运行run方法


27.11 动态代理的概述和实现

       1、动态代理概述

              代理:本来应该自己做的事情,请了别人来做,被请的人就是代理对象

              举例:春节回家买票让人代买

              动态代理:在程序运行过程中产生的这个对象,而程序运行过程中产生对象其实就是我们刚才反射讲解的内容,所以,动态代理其实就是通过反射来生成一个代理。

 

       在Java中java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,通过使用这个类和接口就可以生成动态代理对象。JDK提供的代理只能针对接口做代理

在后面我们有更强大的代理cglib,Proxy类中的方法创建动态代理对象

       Public static Object newProxyInstance(ClassLoaderLoader , Class<?>[] interface , InvocationHandIer h)

       最终会调用InvocationHandler的方法

       InvocationHandler Objectinvoke(Object proxy , Method method , Object[] args)


27.12 模板(Template)设计模式概述和使用

       1、模板设计模式概述

              模板设计模式就是定义一个算法的骨架,而将具体的算法延迟到子类中来实现

       2、优点和缺点

              优点:使用模板方法模式,在定义算法骨架的同时,可以很灵活的实现具体的算法,满足用户灵活多变的需求

              缺点:如果算法骨架有修改的话,则需要修改抽象类

       就相当于是给个月饼模子,可以自己往里面加材料

1、装饰

2、单例

3、简单工厂

4、工厂方法

5、适配器

6、模板


27.13 自己实现枚举类

       1、枚举概述

              是指将变量的值一一列出来,变量的值只限于列举出来的值的范围内。举例:一周只有7天,一年只有12个月等

             

1、回想单例设计模式:单例类是一个类只有一个实例

是单例设计模式的一个扩展

              那么多例类就是一个类有多个实例,但不是无限个数的实例,而是有限个数的实例。这才能使枚举

       4、案例演示

              自己实现枚举类

JDK1.5的新特性

1、自动拆装箱

2、泛型

3、可变参数

4、静态导入

5、增强for循环

6、互斥锁

7、枚举


27.14 通过enum实现枚举类

       1、案例演示

       Java给我们提供的枚举类



27.15 枚举的注意事项

       1、案例演示

              定义枚举要用关键字enum(Class  interface enum)

              所有枚举类都是Enum的子类

              枚举类的第一行上必须是枚举项,最后一个枚举项后的分号是可以省略的,但是如果枚举类有其他的东西,这个分号就不能省略。建议不要省略

              枚举类可以有构造函数,但必须是private的,它默认的也是private的

              枚举类也可以有抽象方法,但是枚举项必须重写该方法

              枚举在switch语句中的使用


27.16 枚举类的常见方法

       1、枚举类的常见方法

              int ordinal()

              int compareTo(E o)

              String name()

             StringtoString()

            <T> T valueOf(Class<T> type, String name)

              values()此方法虽然在JDK文档中查找不到,但每个枚举类都具有该方法,

它遍历枚举类的所有枚举值非常方便

       2、案例演示


27.17 JDK7的六个新特性回顾和讲解

       1、二进制字面量0b001

       2、数字字面量可以出现下划线

       3、switch语句可以用字符串

       4、泛型简化,菱形泛型

       5、异常的多个catch合并,每个异常用或|

       6、try-with-resources语句 即try(){}  自动关流1.7版本标准异常处理代码


27.18 JDK8的新特性

       接口中可以定义有方法体的方法,如果是静态的直接定义,如果是非静态,必须用default修饰


在1.8版本以前局部内部类使用方法中的局部变量时变量必须手动添加final修饰,但在1.8中加不加final都可以,因为系统自动加上了final。

       局部内部类在访问它所在方法中的局部变必须用final修饰,为什么?

              因为当调用这个方法时,局部变量如果没有用final修饰,它的生命周期和方法的生命周期是一样的,当方法弹栈,这个局部变量也会消失,那么如果局部内部类对象还没有马上消失想用这个局部变量,就没有了。如果final修饰会在类加载的时候进入常量池,即使方法弹栈,常量池的常量还在,也可以继续使用。



0 0
原创粉丝点击