"to promise" 这个词在转换、编译器的上下文中是什么意思?

what does the word "to promise" mean in the context of casting, compiler?

来自 java 一本书:

The compiler checks that you do not promise too much when you store a value in a variable. If you assign a subclass reference to a superclass variable, you are promising less, and the compiler will simply let you do it. If you assign a superclass reference to a subclass variable, you are promising more. Then you must use cast so that your promise can be checked at runtime.

如果你能向我解释 "to promise" 在技术问题上的含义,我会明白的。我查了字典,但这个词不适合这个段落的上下文。

这不是标准术语,但作者似乎用它来(试图)让初学者能够理解它。 (这并不容易。)基本上,他们说如果你有:

class Base {
    public void baseMethod() {
        // ...
    }
}
class Derived extends Base {
    public void derivedMethod() {
        // ...
    }
}

你可以这样做:

Base b = new Derived();

...因为 Base 类型定义的所有功能 (baseMethod) 在您分配的对象(Derived 的实例)上可用。你是 "promising",对象 b 所指的将具有 baseMethod,它确实如此。

但是你不能这样做:

Derived d = new Base();

...因为 Derived 类型定义了您正在分配的对象(Base 实例)所没有的特性 (derivedMethod)。你是 "promising",对象 d 指的是 derivedMethod,但它没有,所以你是 "promising too much."


回复您的评论:

how does casting comes in the second example?

它没有出现在那个例子中。转换不会改变对象是什么,只会改变您对它的引用类型。¹

但是假设你有这样的事情:

void someMethod(Base obj) {
    if (obj instanceof Derived) { // Just an example, `instanceof` is usually
                                  // an anti-pattern
        Derived d = (Derived)obj;
        // ...
    }
}

该方法接收一个对象并且只有一个 Base 引用。但是随后代码检查发现该对象实际上是一个Derived(或Derived的子类),因此它使用强制转换来更改其具有的引用类型以便它可以使用Derived 特征。所以铸造就是这样进入的。

再次请注意,在十分之九的情况下,使用 instanceof 是一种反模式。十分之九,您想要重构代码,以便将接口类型传递给仅定义代码所需功能的代码。第十种情况很少见。 :-)

And will casting be always successful in the second one?

仅当您确定该对象属于您要转换为的类型或该类型的子类时。如果你不确定,投射它可能会抛出 ClassCastException.


¹ ...除了将原语(例如 int)转换为其包装器对象(例如 Integer)的特殊情况,反之亦然。即便如此,它也不会 更改 对象,它只是创建一个对象(当转换为包装类型时)或创建一个原始对象(当转换为原始类型时)。