10

有人可以解释类加载和实例化类之间的区别。当我们使用静态变量加载一个类时,它是否也会在加载类的同时被实例化?毕竟静态代码是类的一部分,而不是单独的实例。如果有人提供一个例子来帮助我更好地理解这一点,那将会很有帮助。

4

5 回答 5

11

这是一些很好的解释(带有示例和观察)

在 JVM 中加载和初始化类时 - Java

在 Java 中加载 Class 时

类加载是由 Java 中的 ClassLoaders 完成的,可以实现为在另一个类引用它时立即加载一个类,或者延迟加载该类,直到需要进行类初始化。如果 Class 在实际使用之前被加载,它可以在初始化之前放在里面。我相信这可能因JVM而异。虽然 JLS 保证在需要静态初始化时加载一个类。

当一个类在 Java 中初始化时

当一个类在Java中初始化类加载后,类的初始化发生,这意味着初始化类的所有静态成员。在以下情况下,一个类在 Java 中被初始化:

1)使用 new() 关键字或使用 class.forName() 的反射创建类的实例,这可能会在 Java 中引发 ClassNotFoundException。

2)调用Class的静态方法。

3) 分配一个静态字段Class。

4) 使用了一个类的静态字段,它不是一个常量变量。

5) 如果 Class 是顶级类并且执行词法嵌套在类中的断言语句。

希望有帮助。

于 2013-07-17T07:38:39.463 回答
8
Integer.toString(123);

要使上述静态方法调用起作用,必须加载 Integer 类。

Integer i = new Integer(123);

在上面的代码中,我创建了一个 Integer 类的实例(对象)(显然,它也必须加载才能工作)。

某些类不打算实例化(例如 Math 类,它只有静态方法)。

于 2013-07-17T07:39:16.810 回答
3

类加载
每当 JVM 确定它需要一个类(使用其静态变量、创建新对象、使用其静态方法等)时,它将加载该类并且静态初始化块将运行,静态变量被初始化等。这是(至少在正常情况下)只做一次

SomeClass.someStaticMethod(); //SomeClass is loaded (if its not already)
SomeClass.someStaticVariable; //SomeClass is loaded (if its not already)
SomeClass var=new SomeClass(); //SomeClass is BOTH loaded (if its not already) AND instantiated

因此,以下运行(作为示例):

static Vector3d var=new Vector3d(); //static variables are initialised

static{
    //static initialisation block are run
}

实例化一个类
另一方面,当您使用关键字创建类的实例时,您会实例化一个类;new实例化一个类就是创建一个类的对象。

SomeClass var=new SomeClass(); //SomeClass is instantiating (and loaded if its not already)

结果构造函数运行:

public SomeClass(){
}

{
    //initialisation block(s) also run (but these are very uncommonly used)
}
于 2013-07-17T07:39:10.880 回答
3

类加载器实际上将字节码加载到JVM中,运行静态初始化程序。当你想在类中使用静态字段而不创建它的实例时,必须首先由类加载器加载类。java中的默认类加载器是java.lang.ClassLoader。这个类加载只完成一次.
虽然类实例化正在将类的实例创建到内存中。我们可以使用 .Class 实例化来实例化类,new可以多次进行。例如:Animal a=new Animal();

更多关于类加载

于 2013-07-17T07:53:36.493 回答
2

一个类在被引用时被加载(例如通过Class.forName())。

您通过创建实例来实例化对象,例如

Object o = new Object();

您还可以使用反射来实例化对象。

static加载类时实例化类的成员,例如

public class Sample {
    private static int variable = 10;
}

当我现在加载类时(例如 by Class.forName("Sample");)然后variable用 value 初始化变量10

如果您正在创建一个类的新实例,并且在该类之前(自动)加载之前未加载它。因此,Class.forName()仅在特殊情况下才需要该构造(例如,如果编译时不知道该类)。

于 2013-07-17T07:39:18.610 回答