![](/img/trans.png)
[英]Memory allocation for request and session object in java? Any Difference between them?
[英]Difference between Interface and Class object memory allocation
假设有接口A和class B,class 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();
我的问题是,当编译器编译代码和 memory 分配开始时,我们有两个对象,对吧? 但是一个是A类型,一个是B类型,这意味着'typeInterface'将只有一种方法,但'typeClass'将包含一个字段和一个方法。
这两个对象是否分配相同数量的 memory 或“typeInterface”基本上消耗更少的 memory?
不,您有两个 B 类型的对象,一个存储在 A 类型的引用上,另一个存储在 B 类型的引用上。
两个对象共享相同的 memory 使用大小,但是您不能从类型 A 的引用(名为typeInterface
的引用)访问 B 的方法,即使该方法存在于引用的 object 中,除非您强制转换它。 如果您强制转换引用,则限制将被删除,您可以访问anotherMethod
。
您必须区分引用和对象。 这就是你所需要的。
我的问题是,当编译器编译代码和 memory 分配开始时,我们有两个对象,对吧?
是的。
但是一种是
A
型,一种是B
型,...
不!!
两者都是B
型。 表达式new B(...)
创建一个B
。 之后发生的事情不会改变这一点。
在第一个示例中,您将B
实例的引用分配给类型为A
的变量。 这意味着当您通过该变量访问 object 时,您将只能使用A
功能(方法、字段)。
但是,object 本身仍然是B
的一个实例,并且在 object 的生命周期内将保持这种状态。 我们可以证明它1 。
System.out.println(typeInterface.getClass().getName());
将打印“B”,而不是“A”。
我们可以通过将typeInterface
强制转换为B
并使用B
方法和字段来进一步证明它是一个B
。
它是一个B
。 毫不含糊。
...这意味着“typeInterface”将只有一种方法,但“typeClass”将包含一个字段和一个方法。
不,不正确。 这个逻辑是基于一个错误的假设。 看上面。
这两个对象是否分配相同数量的 memory 或“typeInterface”基本上消耗更少的 memory?
是的,他们使用相同数量的 memory。 它们都是B
实例。 看上面。
理解这一点的一种方法是,当您执行以下任务时:
A typeInterface = new B();
编译器“忘记” typeInterface
(现在)所指的 object 的B
特性。 它只“记住”它指的是某种A
。 但是,在运行时,运行时系统总是知道对象的真实类型是什么,因此它可以正确地实现instanceof
、类型转换、 getClass()
、方法分派等。
1 - Object::getClass()
的 javadoc 状态: “返回此 Object 的运行时Object
” 。
消耗 memory 的是 object 实例。 您的两个实例都是由new B()
创建的,因此它们将占用相同数量的堆 memory。
除了您的两个 object 实例之外,您还有两个指向它们的变量。 这些存储在使用它们的方法的堆栈中。 一个变量需要多少 memory 取决于它是原语还是 object 参考,但仅此而已。 所有 object 引用(不管它们的类型)在那里占用相同数量的空间。
接口只是确保对象在编译时在技术上和逻辑上都满足一定的标准。 执行代码并使用接口时,memory 将被分配,就像您只需使用 class 实例化 object 一样。
所以没有区别(就 memory 分配而言):
A typeInterface = new B();
和
B typeClass = new B();
首先是在堆上分配 sizeof(B) 的新 B() 语句。
二、堆分配地址的赋值存放在变量test中,在栈上分配为sizeof(object *)(即IntPtr.Size,或者32/64位根据硬件+OS+软件运行)。
以下语句在“分配”中完全相同:
B typeClass = new B();
两者之间的唯一区别是可在变量“typeInterface”上调用的方法。
Class:
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 及其对象的 state 及其对象的变量,方法用于实现 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 A {
void hello();
void hello2();
}
我们可以立即以接口为参数定义function
void function example (A i) {
i.hello();
i.hello2();
}
这里究竟会编译什么? 接口 function 调用。
这怎么可能? 这是可能的,因为接口类型变量包含的函数指针与接口中定义的函数一样多。 简而言之,接口是一个包含指向函数的指针变量的结构。
现在任何实现该接口的 class 都可以分配给它。 通过这种分配,指向(接口的)函数的指针变量被“填充”了位于(类的)vmtable 中的函数的地址。
这意味着接口变量总是能看到其中定义的函数,并且只能看到它们(除非强制转换为类)
例如,如果 class 实现了接口。
class B implements A {
public int justAField;
@Override
public void hello() {
System.out.println("Hi.");
}
@Override
public void hello2() {
System.out.println("Hi2.");
}
public void anotherMethod() {
System.out.println("Another one.");
}
}
我们可以有
example(new B());
调用i.hello(); i.hello2();
i.hello(); i.hello2();
触发 class 的相应功能(通过 function 指针)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.