rzw*_*oot 7
不,您误解了演员表操作员。它用于三个完全不相关的任务。你可能知道那5 + 2
是 7,但是"hey" + "bye"
是"heybye"
. +
运算符用于 2 个完全不相关的任务。演员表操作符也不例外。
因此,最好为 的实际语法结构保留名称“cast” (SomeType) someExpr
,即很少使用该术语,而是将名称用于您可以用它做的 3 件完全不相关的事情:
原始转换
当括号中的事物是基元,特别是数字基元时,您会得到这种“模式”:char
, int
, long
, double
, float
, short
, 或byte
。这就是整个列表 - 这些类型在 java 中是硬编码的,你不能制作自己的原语,永远不会有与1不同的原语类型。
在这种模式下,会发生实际的转换:
double y = 5.5;
int x = (int) y;
上面的转换,这是转换运算符的唯一用法。
类型断言
当您在括号中添加非原始类型时,就会出现此模式,并且仅适用于具体化部分(非泛型部分,因此不适<>
用于类型部分中的任何内容)。
这是什么,如果一切顺利,什么都没有。它根本没有做任何事情。它无法转换任何东西。
具体来说,它将注入以下代码:
检查表达式是否实际上是括号中类型的实例。2a. 如果是,那么绝对什么也不做,但为了解析代码和知道要做什么,表达式(String) whatever
是字符串类型,即使whatever
不是。
2b。如果不是,则ClassCastException
当场扔一个。
这就是它所能做的一切。所以,如果它没有抛出异常,它什么也不做。
类型强制/泛型巫毒魔法
为了完整起见,我将其包括在内:在您使用这种特殊的演员模式之前,您不应该使用这种特殊的演员模式,在 Java 中更高级,并且在您了解很多之前,这一切都没有意义爪哇。如果这对你来说听起来像是 gobbledygook,那很好。忽略它,这并不重要。
对于括号中未具体化的东西( 中的东西<>
),它真的真的什么都不做。它不可能抛出任何东西,它实际上归结为零字节码。它只是告诉javac
停止抱怨。是你在告诉编译器:是的,我知道,你不能保证任何代码都有意义。闭嘴,我知道我在做什么。
例子:
List<String> listOfStrings = new ArrayList<String>();
listOfStrings.add("Test");
List raw = listOfStrings;
List<Integer> numbers = (List<Integer>) raw;
以上编译(但带有警告,因为这是没有意义的疯狂代码),并运行,甚至不抛出异常。即使您现在有一个List<Integer>
包含非整数的类型变量。如果您与此列表进行交互,即使您甚至没有编写任何强制转换,ClassCastExceptions 也会开始发生。
狗和猫
您正在执行第二种模式:类型断言。Dog 的实例不是 Cat 的实例,因此:
Dog dog = new Dog();
Cat c = (Cat) dog;
将失败。它实际上会因编译时错误而失败,因为编译器知道它永远不会工作。您可以“修复”它:
Animal a = new Dog();
Cat c = (Cat) a;
现在它将编译,但它会在第二行抛出 ClassCastException。
甚至是什么Animal a = new Dog()
意思?
java中的非基元总是引用。在 java 中不可能有一个包含狗的变量。我知道Dog dog = new Dog()
看起来你有一个名为的变量dog
,其值是一只狗,但事实并非如此。它是对狗的引用。狗太奇怪太大了,变量是非常简单的东西。所有变量都像便利贴一样:它们具有固定的少量空间。对于int
等等boolean
,数字正好适合便利贴,但对于所有非原始人,你不会把狗放在便条上。你在便条上写下狗的位置。Dog dog = new Dog()
只是语法糖:
Dog dog; // make a new postit note
new Dog(); // make a dog object
dog = what we just made; // scribble the dog's location on the note
现在Animal a = new Dog()
是有道理的:Animal a;
两者Dog dog
都只是便利贴。只是a
这里的便利贴受到限制:它可以是空白 ( a = null
),或者它可以包含动物的位置。你可以在上面写下猫、狗、驴或独角兽的位置。但是你不能在上面写房子的位置。dog
注释只能包含狗的位置(或为空白)。
因此,一只狗的位置可以写在任何一张纸条上。
Cat c = (Cat) animal;
方法:
制作一个新的便利贴,为其命名c
,并对其进行限制,使其只能包含猫的位置,或者为空白。
拿名为animal
. 跟随它并检查它引导你的动物是否实际上是一只猫。如果不是,则抛出ClassCastException
.
但如果是,请找到那只猫的位置,然后在标题为“c”的便利贴上乱涂乱画。
这是明智的做法。
[1] 出于原语转换的目的,未来的语言更新(称为 Project Valhalla)不太可能改变这一点,尽管它或多或少会引入让您编写自己的原语的概念。
更多推荐
来回,两个,抽象类
发布评论