"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
)的特殊情况,反之亦然。即便如此,它也不会 更改 对象,它只是创建一个对象(当转换为包装类型时)或创建一个原始对象(当转换为原始类型时)。
来自 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
)的特殊情况,反之亦然。即便如此,它也不会 更改 对象,它只是创建一个对象(当转换为包装类型时)或创建一个原始对象(当转换为原始类型时)。