zoukankan      html  css  js  c++  java
  • Java Class.forName

    Class.forName(xxx.xx.xx) 返回的是一个类

    首先你要明白在java里面任何class都要装载在虚拟机上才能运行。这句话就是装载类用的(和new 不一样,要分清楚)。 

    至于什么时候用,你可以考虑一下这个问题,给你一个字符串变量,它代表一个类的包名和类名,你怎么实例化它?只有你提到的这个方法了,不过要再加一点。 
    A a = (A)Class.forName("pacage.A").newInstance(); 
    这和你 
    A a = new A(); 
    是一样的效果。 

    关于补充的问题 
    答案是肯定的,jvm会执行静态代码段,你要记住一个概念,静态代码是和class绑定的,class装载成功就表示执行了你的静态代码了。而且以后不会再走这段静态代码了。

    Class.forName(xxx.xx.xx) 返回的是一个类 
    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构造。

    What is difference between Class.forName() and Class.forName().newInstance()?

    package test;

    public class Demo {

    public Demo() {
    System.out.println("Hi!");
    }

    @SuppressWarnings("unchecked")
    public static void main(String[] args) throws Exception {
    Class clazz = Class.forName("test.Demo");
    Demo demo = (Demo) clazz.newInstance();
    }
    }

    As explained in its javadoc, calling Class.forName(String) returns the Class object associated with the class or interface with the given string name i.e. it returns test.Demo.class which is affected to theclazz variable of type Class.

    Then, calling clazz.newInstance() creates a new instance of the class represented by this Classobject. The class is instantiated as if by a new expression with an empty argument list. In other words, this is here actually equivalent to a new Demo() and returns a new instance of Demo.

    And running this Demo class thus prints the following output:

    http://stackoverflow.com/questions/2092659/what-is-difference-between-class-forname-and-class-forname-newinstance

    jdbc连接mysql

    new com.mysql.jdbc.Driver();

    也可以,但是访问有限制,要修改下。

    在JAVA中初学者问的最多的就是数据库连接,当然关于数据库连接的方法网上也有很多的教程。说到数据库连接,其中最重要的一点就是Class.forName()和DriverManager.getConnection(url,user,pwd);这两句话。

    首先我们来说说Class.forName(""): 这句话的意思呢就是说我们要先进行驱动的加载,就相当于我们用笔记本要开机首先要给笔记本电池冲上电是一个道理。。那么我们充好电后笔记本要能识别电池才能正常工作。Class.forName("")里面的参数就相当于电池的路径。简单的说:Class是运行中的class类,将forName("className")这个名为className的类装入JVM, 这样就可以动态的加载类,通过Class的反射机制可以获得此类的一些信息。

    而通常我们会在Class.forName("")写成这样Class.froName("").newInstance(); 在后面接上newInstance()有什么用呢?其实很简单:单单使用Class.forName("")是动态加载类是没有用的,其最终目的是为了实例化对象。而Class.forName("").newInstance()返回的是object。有数据库开发经验朋友会发现,为什么在我们加载数据库驱动包的时候有的却没有调用newInstance( )方法呢?即有的jdbc连接数据库的写法里是Class.forName(xxx.xx.xx);而有一些:Class.forName(xxx.xx.xx).newInstance(),为什么会有这两种写法呢?

    Class.forName("");的作用是要求JVM查找并加载指定的类,如果在类中有静态初始化器的话,JVM必然会执行该类的静态代码段。而在JDBC规范中明确要求这个Driver类必须向DriverManager注册自己,即任何一个JDBC Driver的Driver类的代码都必须类似如下:

    Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--> 1 public class MyJDBCDriver implements Driver {

    static {

    DriverManager.registerDriver(new MyJDBCDriver());

    }

    }

    既然在静态初始化器的中已经进行了注册,所以我们在使用JDBC时只需要Class.forName(XXX.XXX);就可以了。

    那么好,了解了Class.forName(""),我们接着来了解下DriverManager.getConnection(url,user,pwd);这个方法是什么意思呢,还是拿笔记本来举例。我们笔记本上了电池了而且机器已经识别了电池并且加载了一定的电量,那么好,现在我们笔记本可以开机了恩,不过开机后,我们还要做一件事情,什么事情呢,我们的电脑上安装了操作系统,那么我们需要选择进入那个操作系统,而url就相当于我们要用哪个数据库。那么如果是个多用户的操作系统,我们要选择相应的用户,那么好user就相当于数据库的用户名。至于pwd很简单,当然就是登陆的密码了。

    好现在我们来具体分析下整个数据库连接类的写法:本写法也就是这样了,好了,下面贴出不同数据库的连接方法:

     java.sql.Connection; 
     import java.sql.DriverManager; 
     import java.sql.SQLException; 
     
     /** 
     * 数据库连接类 
     * 
     * @author funnyking 
     * 
     */ 
     public class SqlConnetction { 
     
         /** 
          * 数据库连接方法(静态) 
          * 
          * @return Connection 
          * @throws ClassNotFoundException 
          * @throws SQLException 
          */ 
         public static Connection getConnetction() throws SQLException { 
             Connection conn = null; 
             try { 
                 // 直连驱动 
                 Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver"); 
     
             } catch (ClassNotFoundException e) { 
                 // TODO Auto-generated catch block 
                 System.out.println("加载驱动异常:" + e.getMessage()); 
             } 
             // 数据库连接地址 
             String url = "jdbc:microsoft:sqlserver://127.0.0.1:1433;DatabaseName=PM"; 
             // 用户名 
             String user = "sa"; 
             // 密码 
             String password = ""; 
             conn = DriverManager.getConnection(url, user, password); 
     
             return conn; 
     
         } 
     
         /** 
          * 关闭Connection方法(静态) 
          * 
          */ 
         public static void getCloseConnettion(Connection conn) { 
             try { 
                 conn.close(); 
             } catch (SQLException e) { 
                 // TODO Auto-generated catch block 
                 System.out.println("关闭数据连接异常:" + e.getMessage()); 
             } 
         } 
     
     }

    1、Oracle8/8i/9i数据库(thin模式) 
    Class.forName("oracle.jdbc.driver.OracleDriver").newInstance(); 
    String url="jdbc:oracle:thin:@localhost:1521:orcl"; 
    //orcl为数据库的SID 
    String user="test"; 
    String password="test"; 
    Connection conn= DriverManager.getConnection(url,user,password);

    2、DB2数据库 
    Class.forName("com.ibm.db2.jdbc.app.DB2Driver ").newInstance(); 
    String url="jdbc:db2://localhost:5000/sample"; 
    //sample为你的数据库名 
    String user="admin"; 
    String password=""; 
    Connection conn= DriverManager.getConnection(url,user,password);

    3、Sql Server7.0/2000数据库 
    Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver").newInstance();
    String url="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=mydb";
    //mydb为数据库 
    String user="sa"; 
    String password=""; 
    Connection conn= DriverManager.getConnection(url,user,password);

    4、Sybase数据库 
    Class.forName("com.sybase.jdbc.SybDriver").newInstance(); 
    String url =" jdbc:sybase:Tds:localhost:5007/myDB"; 
    //myDB为你的数据库名 
    Properties sysProps = System.getProperties(); 
    SysProps.put("user","userid"); 
    SysProps.put("password","user_password"); 
    Connection conn= DriverManager.getConnection(url, SysProps);

    5、Informix数据库 
    Class.forName("com.informix.jdbc.IfxDriver").newInstance(); 
    String url = 
    "jdbc:informix-sqli://123.45.67.89:1533/myDB:INFORMIXSERVER=myserver; 
    user=testuser;password=testpassword"; 
    //myDB为数据库名 
    Connection conn= DriverManager.getConnection(url);

    6、MySQL数据库 
    Class.forName("org.gjt.mm.mysql.Driver").newInstance(); 
    String url ="jdbc:mysql://localhost/myDB?user=soft&password=soft1234&useUnicode=true&characterEncoding=8859_1"
    //myDB为数据库名 
    Connection conn= DriverManager.getConnection(url);

    7、PostgreSQL数据库 
    Class.forName("org.postgresql.Driver").newInstance(); 
    String url ="jdbc:postgresql://localhost/myDB" 
    //myDB为数据库名 
    String user="myuser"; 
    String password="mypassword"; 
    Connection conn= DriverManager.getConnection(url,user,password);

    深入:

    http://blog.csdn.net/zhukejun/article/details/3903552

    http://caterpillar.onlyfun.net/Gossip/JavaEssence/ClassForName.html

  • 相关阅读:
    出错处理函数abort、exit、atexit、strerror. . .
    linux查询系统信息命令
    [转载]比google和百度强十倍的搜索类网站
    陶  朱  商  经
    ip的划分,超详细.【网管常识】
    linux的hostname修改详解
    勤于寻找谈话资料
    Windows常用命令集
    C语言中printf格式
    How to disable SELinux
  • 原文地址:https://www.cnblogs.com/youxin/p/2782424.html
Copyright © 2011-2022 走看看