我对Java中的原语类型short
有一个问题。我使用的是JDK1.6。
如果我有以下信息:
short a = 2;
short b = 3;
short c = a + b;
编译器不想编译——它说它“无法从int转换为short”,并建议我转换为short
,因此:
short c = (short) (a + b);
真的管用。但我的问题是,我为什么要投?a和b的值在short
-短值范围为{-32768,32767}的范围内。当我想执行操作时,我还需要强制转换-,*,/(我还没有检查其他操作)。
如果我对基元类型int
执行相同的操作,我不需要将aa bb强制转换为int
。以下方法很好:
int aa = 2;
int bb = 3;
int cc = aa +bb;
我在设计一个类时发现了这一点,在这个类中,我需要添加两个short类型的变量,编译器希望我进行转换。如果我使用两个int
类型的变量来执行此操作,则不需要强制转换。
一个小提示:原语类型byte
也会发生同样的情况。所以,这是有效的:
byte a = 2;
byte b = 3;
byte c = (byte) (a + b);
但这并不是:
byte a = 2;
byte b = 3;
byte c = a + b;
对于long
、float
、double
和int
,不需要强制转换。仅适用于short
和byte
值。
在C#和Java中,赋值右边的算术表达式默认计算为int。这就是为什么你需要回溯到short,因为出于显而易见的原因,没有从int到short的隐式转换。
编辑:好的,现在我们知道它是Java。。。
Java语言规范第4.2.2节规定:
Java编程语言提供了许多对整数值起作用的运算符:
[...]
换句话说,它就像C#——加法运算符(当应用于整数类型时)只会产生int
或long
,这就是为什么需要强制转换来分配short
变量。
原始答案(C#)
在C#(我猜您还没有指定语言)中,基元类型上唯一的加法运算符是:
int operator +(int x, int y);
uint operator +(uint x, uint y);
long operator +(long x, long y);
ulong operator +(ulong x, ulong y);
float operator +(float x, float y);
double operator +(double x, double y);
这些在C#3.0规范第7.7.4节中。此外,十进制加法定义如下:
decimal operator +(decimal x, decimal y);
这里还定义了枚举添加、字符串连接和委托组合。)
正如您所见,没有short运算符(short x,short y)
运算符,因此两个操作数都隐式转换为int,并使用int形式。这意味着结果是“int”类型的表达式,因此需要强制转换。
正如在简短的C#中所解释的(也适用于其他语言编译器,如Java)
有一个预定义的隐式转换,从短到int,长,浮动,双或十进制。
不能将存储空间较大的非文字数字类型隐式转换为较短的类型(有关整数类型的存储空间,请参见整数类型表)。例如,考虑以下两个短变量x和y:
short x = 5, y = 12;
以下赋值语句将产生编译错误,因为赋值操作符右侧的算术表达式默认计算为int。
short z = x + y; // Error: no conversion from int to short
要解决此问题,请使用强制转换:
short z = (short)(x + y); // OK: explicit conversion
但是,如果目标变量具有相同的存储大小或更大的存储大小,则可以使用以下语句:
int m = x + y;
long n = x + y;
一个好的后续问题是:
"为什么赋值操作符右侧的算术表达式默认计算为int"?
第一个答案可以在以下内容中找到:
整型常数折叠的分类与形式化验证
Java语言规范精确定义了整数的表示方式以及整数算术表达式的求值方式。这是Java的一个重要特性,因为这种编程语言被设计用于Internet上的分布式应用程序。Java程序需要独立于执行它的目标机器生成相同的结果。
相比之下,C语言(以及大多数广泛使用的命令式和面向对象编程语言)更加草率,并留下许多重要的特性。这种不准确的语言规范背后的意图是明确的。同样的C程序应该在16位、32位甚至64位的体系结构上运行,方法是使用目标处理器内置的算术运算实例化源程序的整数算术。这将导致更高效的代码,因为它可以直接使用可用的机器操作。只要整数计算只处理“足够小”的数字,就不会出现不一致。
从这个意义上讲,C整数算法是一个占位符,它不是由编程语言规范精确定义的,而是通过确定目标机器来完全实例化的。
Java精确定义了如何表示整数以及如何计算整数算术。
Java Integers
--------------------------
Signed | Unsigned
--------------------------
long (64-bit) |
int (32-bit) |
short (16-bit) | char (16-bit)
byte (8-bit) |
Char是唯一的无符号整数类型。其值表示Unicode字符,从\u0000
到\uffff
,即从0到216−1.
如果整数运算符的操作数类型为long,则另一个操作数也会转换为long类型。否则,该操作将在int类型的操作数上执行,如有必要,较短的操作数将转换为int。转换规则将精确指定。
Blesner-Blech-COCV 2003:Sabine GLESNER,Jan Olaf BLECH,
Fakultät für Informatik,
卡尔斯鲁厄大学
问题内容: 我很好奇Java的类和double的原始类型之间的性能差异是什么。因此,我创建了一个基准测试,发现类类型比原始类型慢3到7倍。(在本地计算机OSX上为3x,在ideone上为7x) 这是测试: http://ideone.com/fDizDu 那么为什么Double类型要慢得多呢?为什么还要实施它以允许数学运算符? 问题答案: 那么为什么Double类型要慢得多呢? 因为该值包装在需要
我试着搜索像Multi-raw类型的东西,但我没有找到任何东西。 我该怎么做?
问题内容: Java中的原始类型是什么? 基本类型和引用类型之间有什么区别? Java有多少种原始类型,它们是什么? 问题答案: 在Java中,每个变量都有在源代码中声明的类型。类型有两种:引用类型和原始类型。引用类型是对对象的引用。基本类型直接包含值。有8种原始类型: *Byte *Short *Integer *Long *Scorch *Floating *Double *Boolean v
问题内容: 我目前正在尝试从书中学习如何使用泛型。在本章中,它说取一条数据T并将其转换为整数。我正在Eclipse中尝试不同的方法,但是似乎都不允许这样做。您如何执行以下任务: 然后在另一个类中: 我已经尝试使用和其他一些东西,但似乎没有什么能使Java满意。本书坚持要保持方法的通用性,以防使用浮点数或双精度数代替字符串或整数。 编辑:对于其他人可能有类似的问题。从对这个问题的所有评论和被接受的答
如果类型参数在创建期间传递了npt,则原始类型是泛型类或接口的对象。 以下示例将展示上述概念。 例子 (Example) 使用您选择的任何编辑器创建以下Java程序。 GenericsTester.java package com.wenjiangs; public class GenericsTester { public static void main(String[] args) {
我读了很多文章,但我不明白这两行之间的区别: 我看到的唯一区别是第一行触发了“未检查的分配”警告。