请考虑以下事项:
class TypeCast {
public static void main(String[] args) {
byte by = 4; // Compiler casts int literal to byte
int in = 4;
byte byt = in; // Compilation Error: compiler can not cast automatically. WHY?
}
}
我知道编译器可以在文字赋值的情况下缩小范围。但是当赋值涉及变量而不是文字时,它不能做同样的事情。为什么呢?
编辑:我想大多数人都无法理解我想要问的问题。这不是要分配超出范围的'价值在于分配范围内的'值为byte
,让编译器负责缩小范围。这很明显'字节'无法处理超出范围的值,并且需要显式转换(而且我不想知道)。
鉴于价值落在byte
范围内,int
文字作业与byte
和int
类型变量分配到byte
的区别是什么?
答案 0 :(得分:22)
因为在您的代码中,您可以更改变量的值。这就是为什么不允许将int变量赋给一个字节的原因,但是如果你将int变量声明为final,它将允许试试这个:
public class Test {
public static void main(String[] args) {
final int i = 10;
byte by = i;
}
}
这意味着10在字节范围内,所以一切都很好,但如果你写
public class Test {
public static void main(String[] args) {
final int i = 10000;
byte by = i;
}
}
它会给你一个错误,因为10000不在一个字节的范围内。
答案 1 :(得分:7)
恕我直言,主要原因是这样的代码(实际上并没有编译)
int in = ... // what if in == 1234?;
byte byt = in; // then byt == -46. Can you expect this?
是危险的,因为潜在的溢出(int 1234
变为-46
字节)。但是,
byte byt = 4;
是安全,因为非法(溢出)代码如
byte byt = 1234; // doesn't compile
将导致编译时错误。但是,你可以坚持:
// I'm warned about the overflow, but do as I command...
byte byt = (byte) 1234; // -46
或
int in = ...
byte byt = (byte) in; // I know what I'm doing! Cast it, please
答案 2 :(得分:2)
因为将int
分配给byte
通常没有意义;编译器应在这种语句上失败。
编译器接受为字节变量分配文字整数值的原因是它可以(并且确实)在编译时验证该赋值,因此它完全安全,并且实际上并不需要任何类型的"铸造"一点都不如果赋值无效,编译器将失败:
bash$ qjava 'byte b = 128;'
...\QJava.java:4: error: incompatible types: possible lossy conversion from int to byte
byte b = 128;
^
1 error
答案 3 :(得分:1)
byte by = 4是一种特殊情况。没有涉及“强制转换”,因为只允许在字节范围-128到127内的整数值...
尝试使用此范围之外的值,您将获得相同的错误
byte small = -128; // <== OK
byte big = 127; // <== OK
byte tooSmall = -129; // <== error: Type mismatch: cannot convert from int to byte
byte tooBig = 128; // <== error: Type mismatch: cannot convert from int to byte
答案 4 :(得分:1)
您的字节只能代表-128&lt; = X&lt; = 127.
一个字节是8位。第一位是符号,0(正)或1(负)。
对于正数,其他7位代表二进制数。
零是00000000. 127是01111111。
对于否定,它使用名为two's complement的系统。
有两个补码10000000代表-128而没有另一个零。
答案 5 :(得分:0)
如果C#包含字节文字类型,并定义了布尔运算符(Byte | Byte),(Byte ^ Byte),(Byte&amp; Int64),(Int64&amp; Byte),(Byte&amp; UInt64),和(UInt64&amp; Byte)在给定指定的操作数时产生字节结果,然后该语言可合理地要求想要将某些东西存储到Byte
中的代码应该使用类型Byte
的表达式。然而,该语言的创造者可能认为为短于Int32
的类型添加真正支持的好处不足以证明成本合理,因此它只有很少的表达式产生小于{{1 }}
为了允许为短变量赋值的文本值极普遍,因为C#没有其它合理的处理方法,语言允许0到255范围内的整数常量隐式转换为Int32
。类型系统设计中没有任何暗示这种行为的东西 - 它基本上是处理最常见情况的一种方法,在这种情况下缺乏正确的字节类型支持会造成重大烦恼。