zoukankan      html  css  js  c++  java
  • Java类的加载及实例的创建

    java中class.forName()和classLoader都可用来对类进行加载。
    class.forName()前者除了将类的.class文件加载到jvm中之外,还会对类进行解释,执行类中的static块。
    而classLoader只干一件事情,就是将.class文件加载到jvm中,不会执行static中的内容,只有在newInstance才会去执行static块。
    Class.forName(name, initialize, loader)带参函数也可控制是否加载static块。并且只有调用了newInstance()方法采用调用构造函数,创建类的对象

    1、Java创建对象的几种方式

     

    Java创建对象的几种方式(重要):

    (1) 用new语句创建对象,这是最常见的创建对象的方法。
    (2) 运用反射手段,调用java.lang.Class或者java.lang.reflect.Constructor类的newInstance()实例方法。
    (3) 调用对象的clone()方法。
    (4) 运用反序列化手段,调用java.io.ObjectInputStream对象的 readObject()方法。

    (1)和(2)都会明确的显式的调用构造函数 ;(3)和(4)也不会调用构造函数。

     

    2、Class.forName()介绍

     

    在java.lang.Class中,有两个重载的forName方法,分别是:

    1. static Class<?> forName(String className),该方法等价于Class.forName(className, true, this.getClass().getClassLoader())
    2. static Class<?> forName(String className, boolean initialize,ClassLoader loader),其中3个参数分别表示:className - 所需类的完全限定名,initialize - 是否必须初始化类,loader - 用于加载类的类加载器。

     

    forName方法的作用就是:


    使用给定的类加载器,返回与带有给定字符串名的类或接口相关联的 Class 对象。给定一个类或接口的完全限定名,此方法会试图定位、加载和链接该类或接口。指定的类加载器用于加载该类或接口,如果参数loader 为 null,则该类通过引导类加载器加载。只有 initialize 参数为 true且以前未被初始化时,才初始化该类。

     

    public class TestClassForName {
     MyTest tt;
     public static void main(String[] args) throws Exception {
       (new TestClassForName()).loadClass();
     }

     public void loadClass() throws Exception {
       // 会执行静态代码
       // Class<MyTest> clazz = (Class<MyTest>) Class.forName("MyTest", true, getClass().getClassLoader());
       Class<MyTest> clazz = (Class<MyTest>)Class.forName("MyTest");
       // 执行构造函数
       tt = (MyTest)clazz.newInstance();
       // 执行实例方法
       tt.test();

     }
    }

    class MyTest {
     static {
       System.out.println("类的静态初始化块");
     }

     public MyTest() {
       System.out.println("实例化类");
     }
     
     public void test(){
       System.out.println("实例方法");
     }
    }
    类的静态初始化块
    实例化类
    实例方法

     

    3、Class.forName()与new的区别

     

    在java里面任何class都要装载在虚拟机上才能运行。Class.forName(xxx.xx.xx) 返回的是一个类。这句话就是装载类用的(和new 不一样,要分清楚)。

    给你一个字符串变量,它代表一个类的包名和类名,你怎么实例化它?只有用你提到的这个方法了,不过要再加一点。 

    A a = (A)Class.forName("pacage.A").newInstance();
    A a = new A();

    如上的两行代码是等价的。

    jvm会执行静态代码段,静态代码是和class绑定的,class装载成功就表示执行了你的静态代码了。而且以后不会再走这段静态代码了。Class.forName(xxx.xx.xx) 返回的是一个类,作用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段

    动态加载和创建Class 对象,比如想根据用户输入的字符串来创建对象 

    String str = 用户输入的字符串 
    Class t = Class.forName(str); 
    t.newInstance();

    在初始化一个类,生成一个实例的时候,newInstance()方法和new关键字除了一个是方法,一个是关键字外,最主要有什么区别?它们的区别在于创建对象的方式不一样,前者是使用类加载机制,后者是创建一个新类。那么为什么会有两种创建对象方式?这主要考虑到软件的可伸缩、可扩展和可重用等软件设计思想。

    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就可以。

    从JVM的角度看,我们使用关键字new创建一个类的时候,这个类可以没有被加载。但是使用newInstance()方法的时候,就必须保证:1、这个类已经加载;2、这个类已经连接了。而完成上面两个步骤的正是Class的静态方法forName()所完成的,这个静态方法调用了启动类加载器,即加载java API的那个加载器。

     

    现在可以看出,newInstance()实际上是把new这个方式分解为两步,即首先调用Class加载方法加载某个类,然后实例化。 这样分步的好处是显而易见的。我们可以在调用class的静态加载方法forName时获得更好的灵活性,提供给了一种降耦的手段。

     

    最后用最简单的描述来区分new关键字和newInstance()方法的区别: 
    newInstance: 弱类型。低效率。只能调用无参构造。 
    new: 强类型。相对高效。能调用任何public构造。

     
     
     
     
     
     
     
     
     
  • 相关阅读:
    mysql数据与Hadoop之间导入导出之Sqoop实例
    如何将mysql数据导入Hadoop之Sqoop安装
    大数据场景下数据异构之 Mysql实时写入HBase(借助canal kafka SparkStreaming)
    224 绝对路径与相对路径
    223 File类的常用方法
    222 File类概述
    221 输入输出流概述
    220 多线程总结
    219 线程间通信
    218 线程同步-synchronized
  • 原文地址:https://www.cnblogs.com/mazhimazhi/p/9632692.html
Copyright © 2011-2022 走看看