有人可以解释类加载和实例化类之间的区别。当我们使用静态变量加载一个类时,它是否也会在加载类的同时被实例化?毕竟静态代码是类的一部分,而不是单独的实例。如果有人提供一个例子来帮助我更好地理解这一点,那将会很有帮助。
5 回答
这是一些很好的解释(带有示例和观察)
在 Java 中加载 Class 时
类加载是由 Java 中的 ClassLoaders 完成的,可以实现为在另一个类引用它时立即加载一个类,或者延迟加载该类,直到需要进行类初始化。如果 Class 在实际使用之前被加载,它可以在初始化之前放在里面。我相信这可能因JVM而异。虽然 JLS 保证在需要静态初始化时加载一个类。
当一个类在 Java 中初始化时
当一个类在Java中初始化类加载后,类的初始化发生,这意味着初始化类的所有静态成员。在以下情况下,一个类在 Java 中被初始化:
1)使用 new() 关键字或使用 class.forName() 的反射创建类的实例,这可能会在 Java 中引发 ClassNotFoundException。
2)调用Class的静态方法。
3) 分配一个静态字段Class。
4) 使用了一个类的静态字段,它不是一个常量变量。
5) 如果 Class 是顶级类并且执行词法嵌套在类中的断言语句。
希望有帮助。
Integer.toString(123);
要使上述静态方法调用起作用,必须加载 Integer 类。
Integer i = new Integer(123);
在上面的代码中,我创建了一个 Integer 类的实例(对象)(显然,它也必须加载才能工作)。
某些类不打算实例化(例如 Math 类,它只有静态方法)。
类加载
每当 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)
}
类加载器实际上将字节码加载到JVM中,运行静态初始化程序。当你想在类中使用静态字段而不创建它的实例时,必须首先由类加载器加载类。java中的默认类加载器是java.lang.ClassLoader
。这个类加载只完成一次.
虽然类实例化正在将类的实例创建到内存中。我们可以使用 .Class 实例化来实例化类,new
可以多次进行。例如:Animal a=new Animal();
一个类在被引用时被加载(例如通过Class.forName()
)。
您通过创建实例来实例化对象,例如
Object o = new Object();
您还可以使用反射来实例化对象。
static
加载类时实例化类的成员,例如
public class Sample {
private static int variable = 10;
}
当我现在加载类时(例如 by Class.forName("Sample");
)然后variable
用 value 初始化变量10
。
如果您正在创建一个类的新实例,并且在该类之前(自动)加载之前未加载它。因此,Class.forName()
仅在特殊情况下才需要该构造(例如,如果编译时不知道该类)。