接口和 Class 对象内存分配之间的区别
Difference between Interface and Class object memory allocation
假设有接口A和classB,classB实现了该接口;
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 类型的对象,一个存储在 A 类型的引用上,另一个存储在 B 类型的引用上。
两个对象共享相同的内存使用大小,但是您不能从类型 A 的引用(名为 typeInterface
的引用)访问 B 的方法,即使该方法存在于被引用的对象中,除非你投了。如果您转换引用,则限制被删除,您可以访问 anotherMethod
.
您必须区分引用和对象。这就是您所需要的。
消耗内存的是对象实例。您的两个实例都是由 new B()
创建的,因此它们将占用相同数量的堆内存。
除了你的两个对象实例之外,你还有两个指向它们的变量。这些存储在使用它们的方法的堆栈中。一个变量占用多少内存取决于它是原始类型还是对象引用,仅此而已。所有对象引用(不管它们的类型)在那里占用相同数量的 space。
Class:
A class 是用户定义的蓝图或原型,从中创建对象。它表示一种类型的所有对象共有的一组属性或方法。通常,class 声明可以包含这些组件,顺序为:
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, { }.
构造函数用于初始化新对象。字段是提供 class 及其对象状态的变量,方法用于实现 class 及其对象的行为。
界面:
和class一样,接口可以有方法和变量,但是接口中声明的方法默认是抽象的(只有方法签名,没有人)。
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.
Interface 只是确保对象在编译时在技术上和逻辑上都满足特定标准。当执行代码和使用接口时,内存将被分配,就好像您只是使用 class.
实例化对象一样
所以(在内存分配方面)没有区别:
A typeInterface = new B();
和
B typeClass = new B();
首先是在堆上分配 sizeof(B) 的新 B() 语句。
二、堆分配地址的赋值存放在变量test中,在栈上分配为sizeof(object *)(即IntPtr.Size,或者32/64位,基于硬件+OS+软件运行).
以下语句在 'allocations' 中完全相同:
B typeClass = new B();
两者之间的唯一区别是可以在变量上调用的方法 'typeInterface'。
My question is, when compiler compiles the code and when the memory allocation begins, we've got two objects right?
是的。
But one is type A
, one is type B
, ...
没有!!
两者都是B
类型。表达式 new B(...)
创建一个 B
。之后发生的事情不会改变这一点。
在第一个示例中,您将 B
实例的引用分配给类型为 A
的变量。这意味着当您通过该变量.
访问对象时,您将只能使用A
功能(方法、字段)
但是,对象本身仍然是 B
的一个实例,并且在对象的整个生命周期内都将保持这种状态。我们可以证明它1.
System.out.println(typeInterface.getClass().getName());
将打印“B”,而不是“A”。
我们可以更进一步,将 typeInterface
转换为 B
并使用 B
方法和字段......以表明它确实是 B
.
这是一个B
。毫不含糊。
... that means 'typeInterface' will have only one method, but 'typeClass' will contain one more field and one more method.
没有。不对。这种逻辑是基于一个错误的假设。见上文。
Does these two objects allocate the same amount of memory or 'typeInterface' basically consume much less memory?
是的,他们使用相同数量的内存。它们都是 B
个实例。见上文。
理解这一点的一种方法是,当你在这里做作业时:
A typeInterface = new B();
编译器“忘记”了 typeInterface
(现在)引用的对象的 B
-ness。它只“记住”它指的是某种 A
。但是,在运行时,运行时系统总是知道一个对象的真实类型是什么,因此它可以正确地实现instanceof
、type-casts、getClass()
、方法调度等等。
1 - Object::getClass()
的 javadoc 声明:"Returns 此 Object
"[= 的运行时 class 74=].
假设有接口A和classB,classB实现了该接口;
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 类型的对象,一个存储在 A 类型的引用上,另一个存储在 B 类型的引用上。
两个对象共享相同的内存使用大小,但是您不能从类型 A 的引用(名为 typeInterface
的引用)访问 B 的方法,即使该方法存在于被引用的对象中,除非你投了。如果您转换引用,则限制被删除,您可以访问 anotherMethod
.
您必须区分引用和对象。这就是您所需要的。
消耗内存的是对象实例。您的两个实例都是由 new B()
创建的,因此它们将占用相同数量的堆内存。
除了你的两个对象实例之外,你还有两个指向它们的变量。这些存储在使用它们的方法的堆栈中。一个变量占用多少内存取决于它是原始类型还是对象引用,仅此而已。所有对象引用(不管它们的类型)在那里占用相同数量的 space。
Class:
A class 是用户定义的蓝图或原型,从中创建对象。它表示一种类型的所有对象共有的一组属性或方法。通常,class 声明可以包含这些组件,顺序为:
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, { }.
构造函数用于初始化新对象。字段是提供 class 及其对象状态的变量,方法用于实现 class 及其对象的行为。
界面: 和class一样,接口可以有方法和变量,但是接口中声明的方法默认是抽象的(只有方法签名,没有人)。
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.
Interface 只是确保对象在编译时在技术上和逻辑上都满足特定标准。当执行代码和使用接口时,内存将被分配,就好像您只是使用 class.
实例化对象一样所以(在内存分配方面)没有区别:
A typeInterface = new B();
和
B typeClass = new B();
首先是在堆上分配 sizeof(B) 的新 B() 语句。
二、堆分配地址的赋值存放在变量test中,在栈上分配为sizeof(object *)(即IntPtr.Size,或者32/64位,基于硬件+OS+软件运行).
以下语句在 'allocations' 中完全相同:
B typeClass = new B();
两者之间的唯一区别是可以在变量上调用的方法 'typeInterface'。
My question is, when compiler compiles the code and when the memory allocation begins, we've got two objects right?
是的。
But one is type
A
, one is typeB
, ...
没有!!
两者都是B
类型。表达式 new B(...)
创建一个 B
。之后发生的事情不会改变这一点。
在第一个示例中,您将 B
实例的引用分配给类型为 A
的变量。这意味着当您通过该变量.
A
功能(方法、字段)
但是,对象本身仍然是 B
的一个实例,并且在对象的整个生命周期内都将保持这种状态。我们可以证明它1.
System.out.println(typeInterface.getClass().getName());
将打印“B”,而不是“A”。
我们可以更进一步,将 typeInterface
转换为 B
并使用 B
方法和字段......以表明它确实是 B
.
这是一个B
。毫不含糊。
... that means 'typeInterface' will have only one method, but 'typeClass' will contain one more field and one more method.
没有。不对。这种逻辑是基于一个错误的假设。见上文。
Does these two objects allocate the same amount of memory or 'typeInterface' basically consume much less memory?
是的,他们使用相同数量的内存。它们都是 B
个实例。见上文。
理解这一点的一种方法是,当你在这里做作业时:
A typeInterface = new B();
编译器“忘记”了 typeInterface
(现在)引用的对象的 B
-ness。它只“记住”它指的是某种 A
。但是,在运行时,运行时系统总是知道一个对象的真实类型是什么,因此它可以正确地实现instanceof
、type-casts、getClass()
、方法调度等等。
1 - Object::getClass()
的 javadoc 声明:"Returns 此 Object
"[= 的运行时 class 74=].