据我所知,在Java中,没有未签名的数字,它们都是在幕后用魔法签名来理解它.
所以,我对此感到困惑,这可能就是我之前提到过的那种躲避我的魔法.
private static int broadcast = 0xffffffff; //4294967295
Run Code Online (Sandbox Code Playgroud)
我正在使用IntelliJ作为IDE,并且上面的声明工作正常.如果我用小数#替换十六进制数字,我会抱怨数字太大.它是相同的数字,我错过了什么?
我是如何使用它的:
package com.company;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class Main {
private final static int broadcast = 0xffffffff; //4294967295, or 255.255.255.255
private final static int firstClassE = 0xf0000000; //4026531840, or 240.0.0.0
public static int GetIntInetAddress(InetAddress toConvert)
{
final byte[] addr = toConvert.getAddress();
final int ipAddr =
((addr[0] & 0xFF) << (3 * 8)) +
((addr[1] & 0xFF) << (2 * 8)) +
((addr[2] & 0xFF) << (1 * 8)) +
(addr[3] & 0xFF);
return ipAddr;
}
public static Boolean IsClassEAddress(InetAddress address)
{
int curAddr = GetIntInetAddress(address);
System.out.println(String.format("curAddr: %d, firstClassE: %d, broadcast: %d", curAddr, firstClassE, broadcast));
return (curAddr >= firstClassE && curAddr < broadcast) ? true : false;
}
public static void main(String[] args) throws UnknownHostException
{
String ip = "10.20.30.40";
InetAddress someIP = InetAddress.getByName(ip);
if (IsClassEAddress(someIP))
{
// Raise a flag
System.out.println("Class E IP address detected.");
}
// Output of program is:
// curAddr: 169090600, firstClassE: -268435456, broadcast: -1
}
}
Run Code Online (Sandbox Code Playgroud)
在IntelliJ中,还有另一个奇怪的例子就是这种行为.当我检查地址时,检查员显示正确的值和负值,正如我在下面的图片中用红色箭头突出显示的那样.使用Windows calc,我输入-84并转换为十六进制并收到FFF ... FAC.当我输入172时,我只接收AC ...为什么我得到相同的十六进制数,在最大的sig位置前面加1?

这在JLS 3.10.1节中规定,它对十进制文字和其他基数的文字有不同的规则:
如果int类型的十进制文字大于
2147483648(2 31),或者十进制文字2147483648出现在除一元减号运算符(第15.15.4节)的操作数之外的任何地方,则为编译时错误.
VS
下面的十六进制,八进制和二进制文字表示的十进制值-1: ,
0xffff_ffff,
0377_7777_7777和
0b1111_1111_1111_1111_1111_1111_1111_1111
如果一个十六进制,八进制,或二进制INT字面不以32位适合它是一个编译时间错误.
所以这就是编译器以这种方式运行的原因 - 它基本上符合规范.
至于为什么规范是这样写的 ......我怀疑这是因为用非十进制基数写的常量通常用于比特掩码技术之类的东西 - 实际上你只关心值中的位而不是符号和幅度它代表的整数.
0xffffffff作为 int 时为 -1(如果无符号则为 4294967295)。
根据您如何使用该值,这可能并不重要。例如,将值写入二进制文件或将其用作位掩码将写出相同的字节。
如果在java中,您需要实际使用值4294967295作为正数,则需要使用long。
private static long broadcast = 4294967295L;
Run Code Online (Sandbox Code Playgroud)
请注意末尾的“L”,将其标记为长整型。