【问题标题】:Difference between Interface and Class object memory allocation接口和类对象内存分配的区别
【发布时间】:2021-06-05 08:44:52
【问题描述】:

假设有接口A和类B,类B实现了接口;

interface A {
  void hello();
}

class B implements A {
  public int justAField;

  @Override
  public void hello() {
    System.out.println("Hi.");
  }

  public void anotherMethod() {
    System.out.println("Another one.");
  }
}

假设我们有这两个对象;

A typeInterface = new B();
B typeClass = new B();

我的问题是,当编译器编译代码并开始分配内存时,我们得到了两个对象,对吧?但是一个是A型,一个是B型,这意味着'typeInterface'将只有一个方法,而'typeClass'将包含一个字段和一个方法。

这两个对象是否分配相同数量的内存或'typeInterface'基本上消耗更少的内存?

【问题讨论】:

  • 它们消耗的内存量完全相同:即对象引用占用的内存量加上B类的对象消耗的内存量。
  • typeInterfacetypeClass 只是变量。它们指向内存中的对象。两者都指向 B 类的对象。因此正在消耗相同的内存。

标签: java oop memory-management interface jvm


【解决方案1】:

不,您有两个 B 类型的对象,一个存储在 A 类型的引用上,另一个存储在 B 类型的引用上。

两个对象共享相同的内存使用大小,但是您不能从类型 A 的引用(名为 typeInterface 的引用)访问 B 的方法,即使该方法存在于被引用的对象中,除非您强制转换它。如果你投了引用,那么限制就会被移除,你可以访问anotherMethod

您必须区分引用和对象。这就是你所需要的。

【讨论】:

    【解决方案2】:

    消耗内存的是对象实例。您的两个实例都是由new B() 创建的,因此它们将占用相同数量的堆内存。

    除了您的两个对象实例之外,您还有两个变量指向它们。这些存储在使用它们的方法的堆栈中。变量占用多少内存取决于它是原始引用还是对象引用,仅此而已。所有对象引用(无论其类型如何)都占用相同数量的空间。

    【讨论】:

      【解决方案3】:

      类:

      类是用户定义的蓝图或原型,从中创建对象。它表示一种类型的所有对象共有的一组属性或方法。一般来说,类声明可以包括这些组件,按顺序:

      Modifiers: A class can be public or has default access (Refer to this for details).
      Class name: The name should begin with an initial letter (capitalized by convention).
      Superclass(if any): The name of the class’s parent (superclass), if any, preceded by the keyword extends. A class can only extend (subclass) one parent.
      Interfaces(if any): A comma-separated list of interfaces implemented by the class, if any, preceded by the keyword implements. A class can implement more than one interface.
      Body: The class body surrounded by braces, { }.
      

      构造函数用于初始化新对象。字段是提供类及其对象状态的变量,方法用于实现类及其对象的行为。


      界面: 和类一样,接口可以有方法和变量,但是接口中声明的方法默认是抽象的(只有方法签名,没有人)。

      Interfaces specify what a class must do and not how. It is the blueprint of the class.
      An Interface is about capabilities like a Player may be an interface and any class implementing Player must be able to (or must implement) move(). So it specifies a set of methods that the class has to implement.
      If a class implements an interface and does not provide method bodies for all functions specified in the interface, then the class must be declared abstract.
      A Java library example is Comparator Interface. If a class implements this interface, then it can be used to sort a collection.
      

      【讨论】:

        【解决方案4】:

        接口只是确保对象在编译时在技术上和逻辑上都满足特定标准。执行代码并使用接口时,内存将被分配,就像您只是使用类实例化对象一样。

        因此(在内存分配方面)之间没有区别:

        A typeInterface = new B();
        

        B typeClass = new B();
        

        首先是新的 B() 语句,它在堆上分配 sizeof(B)。
        二、堆分配地址的赋值存放在变量test中,在栈上分配为sizeof(object *)(即IntPtr.Size,或者32/64位根据硬件+OS+软件运行)。

        以下语句在“分配”中完全相同:

         B typeClass = new B();
        

        两者之间的唯一区别是可在变量“typeInterface”上调用的方法。

        【讨论】:

          【解决方案5】:

          我的问题是,当编译器编译代码并开始分配内存时,我们得到了两个对象,对吗?

          是的。

          但是一种是A,一种是B,...

          没有!!

          两者都是B 类型。表达式new B(...) 创建一个B。之后发生的事情并没有改变。

          在第一个示例中,您将B 实例的引用分配给类型为A 的变量。这意味着当您通过该变量访问对象时,您将只能使用A 功能(方法、字段)。

          但是,对象本身仍然B 的一个实例,并且在对象的整个生命周期内都将保持这种状态。我们可以证明1

            System.out.println(typeInterface.getClass().getName());
          

          将打印“B”,而不是“A”。

          我们可以更进一步,将typeInterface 转换为B 并使用B 方法和字段...以表明它确实是B

          这是一个B。毫不含糊。

          ...这意味着 'typeInterface' 将只有一种方法,但 'typeClass' 将包含一个字段和一个方法。

          没有。不对。这个逻辑是基于一个错误的假设。见上文。

          这两个对象是否分配相同数量的内存或'typeInterface'基本上消耗更少的内存?

          是的,他们使用相同数量的内存。它们都是B 实例。见上文。


          理解这一点的一种方法是,当你在下面做作业时:

          A typeInterface = new B();
          

          编译器“忘记”B(现在)引用的对象的 B-ness。它只“记住”它指的是A 某种。但是,在运行时,运行时系统总是知道对象的真实类型是什么,从而可以正确实现instanceof、类型转换、getClass()、方法分派等。 p>


          1 - Object::getClass() 的 javadoc 声明:“返回此 Object 的运行时类”

          【讨论】:

            猜你喜欢
            • 2011-03-02
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-10-07
            • 2012-01-13
            • 2014-04-22
            • 1970-01-01
            • 2010-09-27
            相关资源
            最近更新 更多