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