Class类 究竟怎么用

来源:互联网 发布:马士兵java教学视频 编辑:程序博客网 时间:2024/05/12 05:18
                **重点内容**## Class类 究竟怎么用 ##

首先说一点 Class类究竟是什么?概括来讲Class类是描述类的类。我们都知道,java程序其实

是由一个个对象组成,他们属于什么类,继承自什么类,这一系列的信息都是Class类来描述的。类是 描述对象的 ,那类怎么描述呢 Class类。假设A a=new A();a对象的空间中其实有一个指针指向它的Class对象,程序中怎么获取呢?a.getClass().

package learnTest;/* * 我们知道 Java世界是运行在虚拟机之上的,我们的代码 经过编译器 变异之后 生成的是.class 文件。运行期间,我们实例化任何一个类时,jvm 首先会在内存中 * 找有无这个类,若不存在,将这个类加载到内存中,当加载这个类或者是类加载器的define class方法 被调用时,便会为这个类产生一个Class对象,或者说,这 * 个类的Class对象生成,来标识这个类。所有的由该类产生的实例都共同拥有着这个Class对象。若存在,直接创建实例。一般某个类的Class对象被载入内存,它 * 就用来创建这个类的所有对象。注意.class文件并不是所有的都会被加载到内存,只有在需要的时候才会进行加载。 * Class类没有公有的构造方法,那么他是怎么被"创造"出来的呢? * 答:在new 一个 对象时或者加载类加载器时 由jvm自动调用。 * 怎么得到Class对象呢? * 答:1.Class.forName("类的全限定名",boolean initlize,classloader); *     2.Person p=new Person();p.getClass(); *     3.Person.class; * Class类有什么使用技巧? * 1.s lalala=Class.forName(s).newInstance();//s 类的全限定名 *  利用上面代码可以根据存储在s中的类名创建对象。 * 2 虚拟机为每一类(型)管理一个独一无二的Class对象。可以用==比较 类对象。 *  * 一定要明白的: *  1.      forName这句话就是装载类用的(new是根据加载到内存中的类创建一个实例,要分清楚)。  *  2.      至于什么时候用,可以考虑一下这个问题,给你一个字符串变量,它代表一个类的包名和类名,你怎么实例化它? *            A a = (A)Class.forName("pacage.A").newInstance();这和 A a =new A();是一样的效果。 *  3.      jvm在装载类时会执行类的静态代码段,要记住静态代码是和class绑定的,class装载成功就表示执行了你的静态代码了,而且以后不会 *      再执行这段静态代码了。 *  4.      Class.forName(xxx.xx.xx)的作用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段。 *  5.      动态加载和创建Class 对象,比如想根据用户输入的字符串来创建对象 *        String str = 用户输入的字符串   *        Class t = Class.forName(str);   *       t.newInstance(); *  *  *  * *//*二.在初始化一个类,生成一个实例的时候,newInstance()方法和new关键字除了一个是方法,一个是关键字外,最主要有什么区别?1.它们的区别在于创建对象的方式不一样,前者是使用类加载机制,后者是创建一个新类。2.那么为什么会有两种创建对象方式?  这主要考虑到软件的可伸缩、可扩展和可重用等软件设计思想。    Java中工厂模式经常使用newInstance()方法来创建对象,因此从为什么要使用工厂模式上可以找到具体答案。例如:     class c = Class.forName(“Example”);       factory = (ExampleInterface)c.newInstance();   其中ExampleInterface是Example的接口,可以写成如下形式:    String className = "Example";      class c = Class.forName(className);      factory = (ExampleInterface)c.newInstance();  进一步可以写成如下形式:    String className = readfromXMlConfig;//从xml 配置文件中获得字符串   class c = Class.forName(className);     factory = (ExampleInterface)c.newInstance();    上面代码已经不存在Example的类名称,它的优点是,无论Example类怎么变化,上述代码不变,甚至可以更换Example的兄弟类Example2 , Example3 , Example4……,只要他们继承ExampleInterface就可以。    3.从JVM的角度看,我们使用关键字new创建一个类的时候,这个类可以没有被加载。  但是使用newInstance()方法的时候,   就必须保证:        1、这个类已经加载;        2、这个类已经连接了。  而完成上面两个步骤的正是Class的静态方法forName()所完成的,这个静态方法调用了启动类加载器,即加载 Java API的那个加载器。     现在可以看出,newInstance()实际上是把new这个方式分解为两步,即首先调用Class加载方法加载某个类,然后实例化。这样分步的好处是显而易见的。我们可以在调用class的静态加载方法forName时获得更好   的灵活性,提供给了一种降耦的手段。  三.最后用最简单的描述来区分new关键字和newInstance()方法的区别: 1. newInstance: 弱类型。低效率。只能调用无参构造。     2. new: 强类型。相对高效。能调用任何public构造。   */public class ClassLoader_learn {    static {        Person person;        System.out.println("ClassLoader_learn class loaded!");    }    public static void main(String[] args)  {        Class  testClassForName = null,testPointGetclass,testPointclass,testObject;        testPointclass=Person.class;        System.out.println("类名.class-----------"+testPointclass);        try {            testClassForName=Class.forName("learnTest.Person");            System.out.println("Class.forName------"+testClassForName);        } catch (ClassNotFoundException e) {            e.printStackTrace();        }        Person p=new Person();        testPointGetclass=p.getClass();        System.out.println("实例对象.getClass---------"+testPointGetclass);        //创建一个 Person 对象        Person p2=new Person();        testObject= p2.getClass();        if(testClassForName==testPointclass&&testClassForName==testPointGetclass&&testObject==testClassForName){            System.out.println("equal!");        }    }}   

gg

0 0