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

本文详细解析了Java中类的加载过程,包括直接new、使用Class.forName及自定义ClassLoader的不同方式,并介绍了类加载器的层次结构及其工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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 语法基础教程和学习笔记 #### 变量声明与基本数据类型 在 Java 中,变量必须先声明再使用。每一种类型的变量都有固定的内存大小来存储值。以下是几种常见的基本数据类型: - `byte`:8位整数型 - `short`:16位整数型 - `int`:32位整数型 - `long`:64位整数型 - `float`:32位浮点型 - `double`:64位浮点型 - `char`:16位Unicode字符 - `boolean`:布尔逻辑值 (true 或 false) ```java // 声明并初始化不同类型的变量 int age = 20; double height = 1.75; char grade = 'A'; boolean isStudent = true; ``` #### 字符串处理 字符串是 Java 编程中最常用的数据结构之一,在 Java 中表示为 `String` 类的对象。 对于给定的例子,可以通过正则表达式的匹配模式将特定子串替换成其他内容[^1]。 ```java String original = "Hello, Java! Java is fun. Java is powerful."; String modifiedString = original.replaceAll("Java", "Python"); System.out.println("Original String: " + original); System.out.println("Modified String: " + modifiedString); ``` #### 类与对象的概念 面向对象编程的核心概念就是类(class) 和 对象(object),其中类是对具有相同属性和行为的一组实体的抽象定义;而对象则是该类的具体实例化形式。创建自定义类需遵循一定的编码规范,比如 JavaBean 的设计原则就规定了如何构建易于使用的组件[^2]。 ```java public class Person { private String name; public Person(String name){ this.name = name; } // Getter and Setter methods here... } ``` #### 访问控制修饰符 访问权限决定了程序包外或其他类能否访问某个成员(字段或方法)。主要分为四种级别:private、default(package-private)、protected以及public。静态(static)关键字用于描述属于整个类而非单独个体的特性,这意味着即使没有创建任何实例也可以通过类名直接调用来获取这些资源[^3]。 ```java class ExampleClass{ static int sharedData; // Static field void someMethod(){ System.out.println(sharedData); // Accessing the static variable via classname } } ExampleClass.sharedData = 100; // Directly accessing a static member using its containing type's name. ``` #### 文件 I/O 操作优化技术 为了提高文件读写的效率,有会采用特殊的策略如 double-write 来减少实际发生的物理磁盘寻道次数,从而加快速度而不增加额外负担[^4]。 ```java FileOutputStream fos = new FileOutputStream(file); BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(fos)); writer.write(content); writer.flush(); fos.getFD().sync(); // Ensures all changes are written to disk immediately without waiting for buffer flushes or program termination. ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值