java - Java 中动态和静态类型分配之间的区别

标签 java inheritance dynamic static

给定以下类层次结构,以下语句的动态和静态类型是什么?

类层次结构:

class Alpha {}

class Beta extends Alpha {}

class Gamma extends Alpha {}

class Epsilon extends Alpha{}

class Fruit extends Gamma{}

class Golf extends Beta {}

class Orange extends Fruit{}

对于以下每个语句,静态类型?动态类型?:

Fruit f = new Fruit();
Alpha a = f;
Beta b = f;
a = b;
Gamma g = f;

我的回答/问题
我知道 Fruit f = new Fruit() 将是静态和动态类型的 Fruit。
Alpha a = f; 在编译时为 Alpha 类型(静态),在运行时为 Fruit 类型(动态)。
Gamma g = f; 在编译时为 Gamma 类型(静态),在运行时为 Fruit 类型(动态)。
但是我不知道其他两个答案。 Beta b = f 是一个实例,其中同一父类(super class)的两个子类被分配给彼此,所以我不确定它在编译时是 Beta 类型还是 Alpha 类型(静态)。 a = b 是声明后的赋值,所以我不确定答案是什么。有人请帮助我,谢谢!

最佳答案

我正在匆忙打字,所以请原谅任何拼写错误(我稍后会在有机会时修复这些错误)。

I understand that Fruit f = new Fruit() will be of both static and dynamic type Fruit.

我认为您有点混淆了术语 static 和 dynamic 类型与编译时和运行时类型(或者在 C++ 中,当您将类型 A 的对象的地址分配给 a B 类型的指针,B 是 A 的父类。)

除了反射技巧,Java 中没有动态类型。一切都是在编译时静态类型化的。对象在运行时的类型与其编译后的类型相同。

发生的事情是您将对象引用(a、b、c、f)与堆中实例化的实际对象(使用 new 创建的任何对象)混淆了。

在Java中,f是一个对象引用,而不是对象本身。此外,f 的引用类型是Fruit 及其子类。您分配给它的对象 (new Fruit()) 恰好是 Fruit 类型。

现在您的示例代码中的所有其他引用,a 的类型都是对 A 及其子类的引用; b 是类型 对 B 及其子类的引用;等等等等

记住这一点,因为它非常重要。

Alpha a = f; Will be of type Alpha at at compile time (static) and type Fruit at runtime (dynamic).

a 是类型“对类型 A 和子类的引用”。 f 属于“对类型 Fruit 和子类的引用”。

f 指向的对象是“Fruit”类型。当您说“a = f”时,您并不是将“f”分配给“a”。你是说“a 现在将引用 f 当前引用的那个东西”。

那么在赋值之后,a 引用的是什么? Fruit 类型的对象,对象引用 f 在赋值时指向。

请记住,a、b、g、f,它们不是对象。它们是对使用 new 运算符以某种方式创建的对象的引用或句柄。

a、b 或 f 等引用变量与使用 new 创建的对象不同。但恰好前者可以指向后者。

在运行时使用new创建的对象的类型与编译时确定的类型相同。

Gamma g = f; Will be of type Gamma at compile time (static) and type Fruit at runtime (dynamic).

同上。变量 g 是类型对类型 Gamma 和子类的引用 的对象引用。在此分配中,g 指向由 f 指向的同一对象。该对象的类型是什么?编译时给出的相同:Fruit。

However I do not know the other two answers. Beta b = f is an instance in which two subclasses of the same super class are assigned to one another so I'm not sure if it would be of type Beta or type Alpha at compile time (static).

b 是类型对 Beta 类型及其子类的引用。它在赋值后指向的对象 b = fFruit 类型,即它在编译时的类型。

  1. 对象引用 a、b、g 和 f 的类型在编译时确定。它们是静态类型的,不会在运行时更改。

  2. new 创建的对象的类型也在编译时确定。它们也是静态类型的,不会在运行时更改。

  3. 对象,填充对象引用 a、b、g 和 f 指向在运行时,这取决于语句是否被编译器发现有效。赋值可以改变,但这与对象引用或对象本身是静态类型还是动态类型无关。

如果您想清楚区分动态类型和静态类型,请考虑以下内容:

// Java, statically typed.
int x = 3;
x = 5; // good
x = "hi"; // compiler error

## Ruby, dynamically typed
x = 3 # ok
x = 5 # ok
x = "hi" # still ok

然后是强类型语言和弱类型/鸭子类型语言之间的区别(两者都可以动态类型化。)关于这个主题的文献很多。

希望对您有所帮助。

关于java - Java 中动态和静态类型分配之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20504714/

相关文章:

c++ - clang/g++ 与私有(private)继承和使用声明的区别

Scala 隐式类和继承

返回动态旋转数据的 SQL 函数

java - findViewById(R.id.list) 无法解析?

java - Tomcat : NIOConnector throws exception

c++ - 继承编译时还是运行时?

iphone - 如何在iPhone上动态创建sqlite3数据库?

R Shiny 基于复选框输入的多个 slider 动态输入

java - properties.loadFromXML(inputStream) 中的错误 - 将 xml 文件转换为属性文件 Java

java - 为什么不能加载内部类? ClassNotFoundException异常