Java基础知识加强视频的学习:
一、知识点:
17、透析反射的基础_Class类: P224 & P457
(1)、得到一个类的字节码有两种情况,一种是,类的字节码已经加载到内存中,则使用:对象名.getClass()方法,即可得到该对象的类的字节码。
另一种是,类的字节码还未加载到内存中,那么,我们使用Class方法:Class.forName("类名"),利用类加载器加载,放入缓存中,并返回该类的字节码。
(2)、得到各个字节码的Class对象: 1、类名.Class 2、对象名.getClass() 3、静态方法:Class.forName("类名(可以是变量)"),反射的基本方法
(3)、Class类有8个基本的数据类型,分别对应8个Class实际对象,另外一个是void,也有对应的Class对象。
(4)、Integer.TYPE : 包装类型Integer的静态成员变量TYPE代表的是 该包装类型所包装的基本类型的类的字节码,即int.class
(5)、类名.class.isPrimitive(): 该方法确定类是否是基本类型。8个基本类型。 而确定一个数组的Class实例对象,使用 数组名[].class.isArray() 方法。
18、理解反射的概念:
(1)、反射:就是把Java类中的各种成分映射成相应的Java类。
(2)、每个类都具有Field、Method、Constructor、Package等信息,每个类都属于一个包,返回到包又属于一个类,而方法返回的也属于一个Method类,其
成员变量返回到也是一个类。Java中每个类的成员,都属于一个类。
(3)、通过Class类的方法,得到这些类的实例对象,至于有什么用,怎么用,则是学习和应用反射的基本问题。
19、构造方法的反射应用: 反射里边的一个类Constructor
(1)、Constructor类的实例对象代表某个类中的一个构造方法
得到某个类身上的所有的构造方法: eg. Constructor[] constructs = Class.forName("ObjectName").getConstructors()
得到某个类身上的一个构造方法: eg. Constructor constructor = Class.forName("ObjectName").getConstructor()
(2)、在Java中,多个构造方法是使用重载(overlosad)来建立的,而重载仅仅是参数列表的不同,那么,当我们使用getConstructor()方法,在()里边的类型,
我们需要填入我们所想选择的构造函数的形参列表的Class类,例如,如果形参为(String aName),那么所需填入的是String.class。
(3)、注意:1、利用getConstructor得到类的方法时,形参需要类型。2、而在调用获得的方法时,传递的参数,也需要指定对应的类型。
(4)、Class.newInstance()方法: 不用这个方法,也不影响开发,但是,提供该方法,可以提供一个遍历。该方法 是调用Class对象的无参(默认)构造方法。
(5)、如何查看JDK的源代码:在JDK安装目录下的src.zip文件,有JDK的所有的源代码。 反射,运用的不好,会导致程序性能下降。
20、成员变量的反射:
(1)、类的字段,就是类的成员变量,而这些成员在反射得到的结果可以用类Field来表示.
(2)、通过构造方法来给变量来赋值:右击 --> Source --> Generate Constructor Using Field... --> 即利用字段来创建构造函数,使该构造函数在建立类的
对象的时候,可以对变量值来赋值。
(3)、如果定义了一个类引用:Aclass objName = new Aclass(),当我们使用方法: Field argName = objName.getClass().getField("fieldName"),其中,
objName对象属于类Alass的实例。那么,上述语句是这样执行的,首先得到一个Field类型的引用变量argName,然后利用对象objName的方法getClass()
得到其对应的类AClass的字节码(即类Class的一个实例对象),然后用该Class对象的方法getField()来返回字节码中的域fieldName的引用,再将这个引
用赋值给变量argName,该引用是Field类型的。
(4)、Field类型的变量argName并没有指向任何类Aclass的实例对象的变量,只是指向类Aclass的字节码中的变量,只有指向某个对象时,argName才能指向其值。
(5)、如果我们实例化了一个Aclass的对象objName,并用getField从该对象中得到了域引用argName,那么,我们可以使用方法:argName.get("实例对象名"),来
获得该对象的域(argName所指的域)的值。
(6)、暴力反射:当所访问的对象是private型的时候,我们不能直接得到该值,必须将该变量的访问属性设置为可访问:利用 argName.setAccessible(true),其中true表示
可访问,如果是false表示不可访问。
二、问题与收获:
(1)、对于比较运算符“==”,其比较的左右限制是非常大的。例如,类int.class == double.class 不能比较,但是int.class == Integer.class却可以比较。
那么,我们该如何比较两个不同的字节码是否一样呢 ?
(2)、AOP 与 OPP :
AOP = Aspect Oriented Programming 面向方法编程
OOP = Object Oriented Programming 面向对象编程
(3)、Class类没有构造方法: Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的。
(4)、反射和内省:
反射:reflection .是指一类应用,它们能够自描述和自控制。也就是说,这类应用通过采用某种机制来实现对自己行为的描述(self-representation)
和监测(examination),并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。
内省:introspection(介绍).
(5)、Object class,是所有Java classes的继承根源,其内声明了数个应该在所有Java class中被改写的methods:hashCode()、equals()、clone()、
toString()、getClass()等。在java.lang.reflect包中有三个类Field,Method,Constructor.分别描述域,方法,构造器。
(6)、在JDK文档中,当我查阅一个函数或者相关文档时,在文档说明下会用Since: + JDK版本 。 这就是 说,该文档或者方法是在什么时候引入或创建的。
而所谓的版本新特性,就是指该版本新加入的东西。
(7)、SRC:abbr. 标准要求代码(=Standard Requirement Code),JDK中所有的源代码,都在这里。
(8)、在20.(3)中,我们使用 syo语句输出(argName),我们得到的将是: 对象的完整类名.变量名
(9)、在编程中,我们使用一个心得的方式的时候,最后在后面注释原因,以此来突出。