当我们使用new运算符创建对象时,它是否使用实际的.class文件在java中创建对象

问题描述 投票:6回答:2

我对一个主题感到困惑,无法在网上找到它。据我了解,当程序启动时,类加载器加载.class文件并将它们作为Class类型的对象存储在内存中。

我的问题是我们何时使用:

Test test = new Test();

是使用.class文件创建新对象,还是使用内存中已有的Class对象?

java class classloader new-operator
2个回答
5
投票

将类加载到JVM后,不会再为同一个类加载器加载相同的类。将从内存中的类对象创建新实例(对于相同的类加载器)。

高级步骤(从https://www.ibm.com/developerworks/java/tutorials/j-classloader/j-classloader.html复制)

  1. 调用findLoadedClass以查看是否已加载该类。
  2. 如果还没有加载类,则使用findClass获取字节(由类加载器实现覆盖)。
  3. 如果找到原始字节,请调用defineClass将它们转换为Class对象。 (AppClassLoader中的示例)
  4. 如果类已解析,请调用resolveClass来解析Class对象。
  5. 如果仍然没有类,则抛出ClassNotFoundException。 protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { // First, check if the class has already been loaded Class c = findLoadedClass(name); if (c == null) { try { if (parent != null) { c = parent.loadClass(name, false); } else { c = findBootstrapClass0(name); } } catch (ClassNotFoundException e) { // If still not found, then invoke findClass in order // to find the class. c = findClass(name); } } if (resolve) { resolveClass(c); } return c; }

以下示例将打印相同的hashCode并引用相同的Test.class

    Test  test1 = new Test();
    Test test2 = new Test();
    System.out.println(test2.getClass().hashCode());
    System.out.println(test1.getClass().hashCode());
    System.out.println(Test.class.hashCode());

有关详细信息http://www.onjava.com/pub/a/onjava/2005/01/26/classloading.html?page=1


1
投票

类(.class)被加载到方法区域(每个JVM 1个)。这也是堆的逻辑部分。

因此,在您的情况下,当通过main方法或其他类作为依赖项加载时,Test.class将出现在方法区域中,如下所示:

方法区域为每个加载的类存储以下数据:

  1. 运行时常量池
  2. 字段和方法数据
  3. 方法和构造函数的代码

遇到new Test()时,将在堆中创建一个Test类的新实例,该实例表示Test类型的Object。

enter image description here

Where does class, object, reference variable get stored in java. IN heap or stack? Where is heap or stack located?

上面的帖子更详细地解释了JVM中的存储原理。

© www.soinside.com 2019 - 2024. All rights reserved.