`
lixiao
  • 浏览: 14601 次
  • 性别: Icon_minigender_1
  • 来自: 上海
最近访客 更多访客>>
社区版块
存档分类
最新评论

[笔记]Class.forName 时static代码的运行

    博客分类:
  • java
阅读更多

Java 类的装载过程
查看Java load class 的信息:
java -verbose:class MyClass

 

测试代码

public class MyTest{
    public static void main(String args[]) throws ClassNotFoundException,
            InstantiationException, IllegalAccessException {
        Class cla = Class
                .forName("A", true, CRCCheckSum.class.getClassLoader());
        System.out.println("After Class.forName(). Before class.newInstance()");
        cla.newInstance();
        new A();
        Class.forName("A"); // find class A ,skip load
    }
}
class A {
    public A() {
        System.out.println("public A() Constructor");
    }

    static {
         System.out.println("static Code");
    }

    { System.out.println("non static Code");
    }
}

 输出:

static Code
After Class.forName(). Before class.newInstance()
non static Code
public A() Constructor
non static Code
public A() Constructor

 

我的理解:

让Java加载类有三种情况,

1.直接new ,如:new MyClass();

2.Class.forName, 如:Class.forName ("org.gjt.mm.mysql .Driver")

3.定义ClassLoader,用其loadClass方法.

 

JVM加载一个未加载过的类分几步:

a.装载 b.连接 c.初始化 d.实例化

 

对于1.直接就abcd连着执行了

对于2.其有两个方法可以选择是ab,还是abc.

对于3.如果改变实现似乎可以控制到a,和ab.

 

1就不分析了.

 

对于2

有两个方法:

1)Class.forName(String className)

2)Class.forName(forName (String  name, boolean initialize, ClassLoader  loader)

后者的initialize参数是指名,是否需要在装载连接完毕类后,进行初始化的工作.也就是执行static代码等.

如果Class.forName("MyClass") 则相当于:Class.forName("MyClass",true,this.getClass.getClassLoder());

这个也就是为什么要用

Class.forName("com.mysql.jdbc.Driver" ); 来注册driver

因为com.mysql.jdbc.Driver中有这样的代码:

public class Driver extends NonRegisteringDriver
{
    public Driver() throws SQLException
    { }

    static


    {
        try {
            DriverManager.registerDriver(new Driver());


        }
        catch(SQLException E) {
            throw new RuntimeException("Can't register driver!");
}}}

 这样调用,由于在Class.forName进行加载的时候会自动执行初始化,也就是想DriverManager注册自己.

 所以就不必再用newInstance()来生成一个实例.

 

对于3.有这样两个方法

ClassLoader.loadClass(String className);

protected ClassLoader.loadClass(String className,boolean resolve);

关于resolve的行为还不太懂,改天继续写.

 

classLoder 层次:

  bootstrap classloader
                 |
  extension classloader
                 |
  system classloader

 

获得bootstrap classLoader加载哪些内容:

       URL[] urls=sun.misc.Launcher.getBootstrapClassPath().getURLs();
        for (int i = 0; i < urls.length; i++) {
          System.out.println(urls[i].toString());
        }

 

获得SystemClassLoader(): ClassLoader.getSystemClassLoader()

获得ExtensionClassLoader():ClassLoader.getSystem.ClassLoader().getParent();

 

参考文章:

http://www.iteye.com/topic/25053

http://www.iteye.com/topic/189897

http://www.iteye.com/topic/11003

http://www.iteye.com/topic/12084

http://www.iteye.com/topic/68170

http://www.iteye.com/topic/70217

 

分享到:
评论

相关推荐

    JAVA上课笔记class_07

    根据给定的信息,我们可以总结出本篇JAVA上课笔记class_07主要讲解的是Java反射机制的相关知识点。反射机制是Java语言的一个重要特性,它允许在运行时检查类、接口、字段和方法等信息,并能够创建对象及调用方法。...

    JAVA反射笔记 md格式

    通过`Class.forName()`或对象的`getClass()`方法可以获得。 - **Constructor对象**:表示类的构造器,通过`Class.getConstructors()`或`Class.getDeclaredConstructors()`获取。 - **Method对象**:表示类的方法,...

    day021-反射和注解笔记和代码.rar

    1.1 Class clazz = Class.forName(全限定路径名) (最多使用)默认就是调用下面的方法 1.2 static 类&lt;?&gt; forName(String name, boolean initialize, ClassLoader loader) name:全限定路径名 ...

    C#学习笔记_20100614.pdf

    但是,如果你确实需要这样做,比如当你从另一种语言移植代码时遇到了问题,C#允许通过在关键字前添加`@`符号来解决这个问题。例如: ```csharp using System; class Test { static void Main() { string @string =...

    JDBC学习笔记(笔记+包含详细注释的代码)

    Class.forName("com.mysql.jdbc.Driver"); // 加载驱动 Connection conn = DriverManager.getConnection( "jdbc:mysql://localhost:3306/mydb", "username", "password"); Statement stmt = conn....

    开发笔记API.md

    ### 开发笔记API知识点概述 #### 一、Java对象与Map之间的转换 ##### 1.1 Object转换Map **代码示例:** ```java Field[] fields = Object.getClass().getDeclaredFields(); try { for (Field field : fields) ...

    2_JDBC笔记.pdf

    1. **加载驱动**:首先需要在Java程序中加载对应的数据库驱动,这通常通过`Class.forName()`方法完成,传入数据库驱动类的全限定名。 2. **连接数据库**:使用`DriverManager.getConnection()`方法,传入数据库URL、...

    传智播客JDBC技术全程笔记

    注册驱动的方式有三种,分别是通过`Class.forName()`、`DriverManager.registerDriver()`以及设置系统属性。 - **推荐方式**:`Class.forName()` ```java Class.forName("com.mysql.jdbc.Driver"); ``` 这种...

    java笔记.txt

    - 示例代码:`public class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!"); } }` - `public`: 表示访问级别,允许外部访问。 - `class`: 定义一个类的关键字。 - ...

    Python学习笔记.docx

    在Python编程语言中,有效地访问数据结构是提升代码效率的关键。元组作为不可变序列,是Python中的一个重要数据类型。本篇笔记将探讨如何优化元组的访问效率,并介绍一些实用技巧。 首先,当我们需要访问元组中的...

    JDBC 实战教程-尚硅谷学习笔记 ,2022版

    - **数据库连接**:使用`Class.forName()`加载驱动,然后通过`DriverManager.getConnection()`建立与数据库的连接。 **2. 数据库操作** - **SQL语句执行**:JDBC提供`Statement`和`PreparedStatement`接口,前者...

    Java笔记-通过反射获取注解及Spring中获取某包下的所有class文件

    1. 获取目标类的`Class`对象,例如:`Class&lt;?&gt; clazz = Class.forName("YourClassName");` 2. 调用`getAnnotation(Class&lt;? extends Annotation&gt; annotationType)`方法,传入你感兴趣的注解类型。例如,如果你要获取`...

    J2EE-JDBC学习笔记

    3. **利用`Class.forName()`方法** ```java Class.forName("com.mysql.jdbc.Driver"); ``` 这是最常用且推荐的方式,通过反射机制加载并初始化驱动。该语句在JVM启动时通过静态代码块注册驱动到`DriverManager`...

    JDBC学习笔记

    Class.forName(driverName); // 建立连接 conn = DriverManager.getConnection(url, username, password); // 创建Statement对象 stmt = conn.createStatement(); // 执行查询语句 String sql = ...

    mybatis开发笔记.docx

    public static void main(String[] args) throws IOException { // 加载配置文件 String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); // 构建会话...

    C#学习笔记_20100614

    ### C#学习笔记知识点梳理 #### C#中关键字的小提示 C#作为一种强类型的语言,对关键字有着严格的规范。为了防止命名冲突,C#不允许使用关键字作为标识符。但是,在某些特殊情况下,如果确实需要使用关键字作为...

    linux mysql-connector-java-5.1.36.tar.gz

    - 在Java代码中,通过`Class.forName("com.mysql.jdbc.Driver")`加载驱动,然后使用`DriverManager.getConnection()`方法建立数据库连接。 4. **使用示例**: ```java import java.sql.Connection; import java...

Global site tag (gtag.js) - Google Analytics