- 已关闭。**此问题为not reproducible or was caused by typos。当前不接受答案。
这个问题是由打字错误或无法再重现的问题引起的。虽然类似的问题在这里可能是on-topic,但这个问题的解决方式不太可能帮助未来的读者。
17小时前关门了。
Improve this question
public class main {
public static void main(String[] args) {
double num = 324.2;
System.out.println((int)num);
}
}
上面的代码是类型转换的一个例子吗?
2条答案
按热度按时间n3h0vuf21#
非正式地说,是的。Java程序员(包括我自己)经常将其称为类型转换。
但严格地说,Java语言规范(JLS)没有定义,甚至没有在任何地方使用短语“type cast”或“typecast”(您可以通过文本搜索PDF版本的规范来确认这一点,我正在查看最新版本)。
根据JLS,
(int) num
是 * 强制转换表达式 * 的示例;参见JLS 15.16。该操作在其操作数上执行 * 强制转换 *。bmp9r5qi2#
所有类型转换都是"类型转换";事实上,"类型转换"作为一个术语并没有出现。
使用这个术语特别危险,几乎不应该使用cast。
问题是,这是"强制转换操作符":
(Type) expression;
.它做了5件不同的事情,其中一些是彼此完全无关的。一个真正的枪和祖母的情况。就像这样不同:
它们都使用
+
,都被称为"加运算符",但是一个做数字加法,另一个做完全不相关的字符串连接。对于强制转换操作符也是如此。
原语转换
如果括号中的"type"是一个基元类型,那么java会将表达式视为基元类型(它必须是基元类型,或者是一个装箱类型,在这种情况下,它会将其取消装箱),然后convert。这是**转换操作符可以做的各种事情中唯一的一件。例如:
这个函数把
x
当作一个基元(它已经是基元了,所以它不做任何事情),然后转换它。double到int的转换去掉了小数点分隔符后面的内容,所以,y现在是5。类型强制
这不会转换任何内容。java生成以下代码:
表达式
x
实际上指向的对象是String
的示例或String
的某个子类型吗?如果是-〉完全不做任何事情并继续;就
javac
而言,表达式(String) x
是String
类型,即使x
不是。如果否-〉,则抛出
ClassCastException
。在任何情况下,这都不会转换任何内容。例如:
甚至都不会编译。即使你试图编译它:
你会得到一个ClassCastException异常。
类型Assert
这里括号中唯一值得注意的部分是
<String>
部分-泛型。这部分只是作为程序员所做的Assert。您告诉javac将表达式(List<String>) o
视为List<String>
类型,即使o
不是。Java什么也不做。此代码在运行时不能失败。即使在上面的情况下,* 是一个非字符串! *-java会盲目地继续。但是,x
现在是'堆污染',它的类型是List<String>
,但实际上指向一个没有字符串的列表。这意味着稍后如果你这样做:你会得到一个
ClassCastException
,这很奇怪,因为这一行没有强制类型转换!-然而,这就是它的工作原理。通常你应该避免类型Assert。当你写一个类型Assert时,javac
会警告你。显式类型加宽
java中的类型自动加宽例如,如果您有以下方法:
你可以用
foo("Hello")
来调用它。尽管"Hello"
是一个String--但是所有的String都是Object,所以String只在需要Object的时候才起作用,你不需要强制转换它。但是,如果你愿意,你可以这样做。通常这是没有意义的,但是如果有多个重载,这就很重要了。假设:你可以调用
foo("Hello")
,它将打印'String variant'。但是,你也可以写:这将打印"Object variant"。(重载是静态调度的;它是动态调度的重写)。
这是一个相当重要的代码气味,如果这曾经出现过。
Lambda强制
在java中,闭包/lambda是允许的,但是必须放在一个上下文中,在该上下文中,你可以清楚地知道你想要什么类型,并且该类型必须是Functional Interface类型。例如:
是合法的java,但这只是因为
Runnable r =
部分告诉java你希望它是一个Runnable
(Runnable
是一个函数接口,因此没问题)。因为
Object
不是一个函数接口。你可以用一个强制转换来强制它。这个编译:你很少需要这个。
关闭通知
除非你在谈论语法本身,否则不要使用"cast"这个词(很少需要谈论这个),而要使用"primitive type convert"、"type coerce"或"type assert"。
注意:最后两种奇特的情况是使用类型强制来实现一个目标,而不是实际强制一个类型。