2016-11-24 88 views
1

我有一类学生是的Java class.forClass()VS类声明

package org.ahmed; 

public class Student { 

    public Student() { 
     // TODO Auto-generated constructor stub 
     System.out.println("Generated constructor"); 
    } 

    static { // static block 
     System.out.println("Hello world static"); 
    } 

    { // insance block 
     System.out.println("Hello world non static"); 
    } 
} 

然后

public class Main { 

    public static void main(String[] args) throws ClassNotFoundException { 
     Class.forName("org.ahmed.Student"); // this line causing static block execution in Student class 
     // Student s; // this line doesn't execute the static block. 
    } 
} 

我用Class.forClass()我们可以动态运行在运行任何 类明白。但在其他情况下,我有一些关于 静态块的问题。

如果我在我的main方法中使用Class.forClass("org.ahmed.Student"),那么它的执行Student的静态块为 。但是,如果我在 main方法中声明Student s它不执行静态块。我认为 Class.forClass("ClassName")是相同的声明类与变量 名称。

+0

实际上,它是'Class.forName()',而不是'Class.forClass()'。 –

回答

2

当您使用Class.forName("org.ahmed.Student")你居然强制JVM加载类和调用其静态块。您可以阅读更多here

+0

因此,如果我只是用变量名声明类引用,那么静态执行是不能保证的?像学生的? –

-1

声明类引用将类加载到JVM,因此将执行静态块。我能看到

Student s; 

实施例的静态块执行:

package com.snofty.test; 

公共类类加载{

public ClassLoading(){ 
    System.out.println("in constructor"); 
} 
static { 
    System.out.println("in static block"); 
} 

{ 
    System.out.println("in instance block"); 
} 
public static void main(String[] args) { 
    ClassLoading classLoading; 

} 

}

Class.forName() 

它是用来加载该类动态地通过传递cl屁股名称 例如

public void loadClass(String className){ 
    Class.forName(className); 
} 
+1

学生,在我的情况下不会导致静态执行!!! –

+0

我的不好..我正在执行相同类的ClassLoaderTest类中的主要方法,因此能够看到静态块执行.. – snofty

1

javadoc

调用Class.forName(className)方法是 等效于:Class.forName(className, true, currentLoader),其中第二参数指定类是否将被初始化。

所以,如果你不想初始化类,只需要调用与初始化方法=假,如:

Class.forName("org.ahmed.Student", false, this.getClass().getClassLoader())} 
+0

感谢您的答案。 –

3

装载类(JLS§5.3而且我认为,JLS§5.4)和之间的区别初始化类(JLS§5.5)。默认情况下,Class.forName既可以,但有an override you can use可让您控制是否初始化该类。

只声明一个Student变量不会初始化该类。实际上,即使是指Student.class也不会初始化这个类。你必须做一些事情来触发初始化,如使用newgetstaticputstatic,或invokestatic字节码操作与类的东西(但看到§5.5链接查看详情,有初始化类其他东西)。

因此,举例来说,如果你给Student公共领域:

public static String foo = "bar"; 

...然后在Main.main你这样做:

System.out.println(Student.foo); 

... 将引发的初始化班上。

+0

感谢您的回答。 @ T.J。克劳德 –