下面这个示例展示了哪些基本数据类型能用于哪些特定的操作符。基本上这是一个不断重复的示例,只是每次使用了不同的基本数据类型。程序能正常编译,因为那些会导致编译失败的行已经用//-注释掉了。

    1. // operators/AllOps.java
    2. // 对每个基本数据类型都测试一遍所有操作符
    3. // 以此显示哪些能被Java编译器所接受
    4. public class AllOps {
    5. // boolean类型测试
    6. void f(boolean b) {}
    7. void boolTest(boolean x, boolean y) {
    8. // 算术操作符:
    9. //- x = x * y;
    10. //- x = x / y;
    11. //- x = x % y;
    12. //- x = x + y;
    13. //- x = x - y;
    14. //- x++;
    15. //- x--;
    16. //- x = +y;
    17. //- x = -y;
    18. // 关系操作符和逻辑操作符:
    19. //- f(x > y);
    20. //- f(x >= y);
    21. //- f(x < y);
    22. //- f(x <= y);
    23. f(x == y);
    24. f(x != y);
    25. f(!y);
    26. x = x && y;
    27. x = x || y;
    28. // 按位操作符:
    29. //- x = ~y;
    30. x = x & y;
    31. x = x | y;
    32. x = x ^ y;
    33. //- x = x << 1;
    34. //- x = x >> 1;
    35. //- x = x >>> 1;
    36. // 复合赋值:
    37. //- x += y;
    38. //- x -= y;
    39. //- x *= y;
    40. //- x /= y;
    41. //- x %= y;
    42. //- x <<= 1;
    43. //- x >>= 1;
    44. //- x >>>= 1;
    45. x &= y;
    46. x ^= y;
    47. x |= y;
    48. // 类型转换:
    49. //- char c = (char)x;
    50. //- byte b = (byte)x;
    51. //- short s = (short)x;
    52. //- int i = (int)x;
    53. //- long l = (long)x;
    54. //- float f = (float)x;
    55. //- double d = (double)x;
    56. }
    57. void charTest(char x, char y) {
    58. // 算术操作符:
    59. x = (char)(x * y);
    60. x = (char)(x / y);
    61. x = (char)(x % y);
    62. x = (char)(x + y);
    63. x = (char)(x - y);
    64. x++;
    65. x--;
    66. x = (char) + y;
    67. x = (char) - y;
    68. // 关系操作符与逻辑操作符:
    69. f(x > y);
    70. f(x >= y);
    71. f(x < y);
    72. f(x <= y);
    73. f(x == y);
    74. f(x != y);
    75. //- f(!x);
    76. //- f(x && y);
    77. //- f(x || y);
    78. // 按位操作符:
    79. x= (char)~y;
    80. x = (char)(x & y);
    81. x = (char)(x | y);
    82. x = (char)(x ^ y);
    83. x = (char)(x << 1);
    84. x = (char)(x >> 1);
    85. x = (char)(x >>> 1);
    86. // 复合赋值:
    87. x += y;
    88. x -= y;
    89. x *= y;
    90. x /= y;
    91. x %= y;
    92. x <<= 1;
    93. x >>= 1;
    94. x >>>= 1;
    95. x &= y;
    96. x ^= y;
    97. x |= y;
    98. // 类型转换:
    99. //- boolean bl = (boolean)x;
    100. byte b = (byte)x;
    101. short s = (short)x;
    102. int i = (int)x;
    103. long l = (long)x;
    104. float f = (float)x;
    105. double d = (double)x;
    106. }
    107. void byteTest(byte x, byte y) {
    108. // 算术操作符:
    109. x = (byte)(x* y);
    110. x = (byte)(x / y);
    111. x = (byte)(x % y);
    112. x = (byte)(x + y);
    113. x = (byte)(x - y);
    114. x++;
    115. x--;
    116. x = (byte) + y;
    117. x = (byte) - y;
    118. // 关系操作符与逻辑操作符:
    119. f(x > y);
    120. f(x >= y);
    121. f(x < y);
    122. f(x <= y);
    123. f(x == y);
    124. f(x != y);
    125. //- f(!x);
    126. //- f(x && y);
    127. //- f(x || y);
    128. // 按位操作符:
    129. x = (byte)~y;
    130. x = (byte)(x & y);
    131. x = (byte)(x | y);
    132. x = (byte)(x ^ y);
    133. x = (byte)(x << 1);
    134. x = (byte)(x >> 1);
    135. x = (byte)(x >>> 1);
    136. // 复合赋值:
    137. x += y;
    138. x -= y;
    139. x *= y;
    140. x /= y;
    141. x %= y;
    142. x <<= 1;
    143. x >>= 1;
    144. x >>>= 1;
    145. x &= y;
    146. x ^= y;
    147. x |= y;
    148. // 类型转换:
    149. //- boolean bl = (boolean)x;
    150. char c = (char)x;
    151. short s = (short)x;
    152. int i = (int)x;
    153. long l = (long)x;
    154. float f = (float)x;
    155. double d = (double)x;
    156. }
    157. void shortTest(short x, short y) {
    158. // 算术操作符:
    159. x = (short)(x * y);
    160. x = (short)(x / y);
    161. x = (short)(x % y);
    162. x = (short)(x + y);
    163. x = (short)(x - y);
    164. x++;
    165. x--;
    166. x = (short) + y;
    167. x = (short) - y;
    168. // 关系操作符与逻辑操作符:
    169. f(x > y);
    170. f(x >= y);
    171. f(x < y);
    172. f(x <= y);
    173. f(x == y);
    174. f(x != y);
    175. //- f(!x);
    176. //- f(x && y);
    177. //- f(x || y);
    178. // 按位操作符:
    179. x = (short) ~ y;
    180. x = (short)(x & y);
    181. x = (short)(x | y);
    182. x = (short)(x ^ y);
    183. x = (short)(x << 1);
    184. x = (short)(x >> 1);
    185. x = (short)(x >>> 1);
    186. // 复合赋值:
    187. x += y;
    188. x -= y;
    189. x *= y;
    190. x /= y;
    191. x %= y;
    192. x <<= 1;
    193. x >>= 1;
    194. x >>>= 1;
    195. x &= y;
    196. x ^= y;
    197. x |= y;
    198. // 类型转换:
    199. //- boolean bl = (boolean)x;
    200. char c = (char)x;
    201. byte b = (byte)x;
    202. int i = (int)x;
    203. long l = (long)x;
    204. float f = (float)x;
    205. double d = (double)x;
    206. }
    207. void intTest(int x, int y) {
    208. // 算术操作符:
    209. x = x * y;
    210. x = x / y;
    211. x = x % y;
    212. x = x + y;
    213. x = x - y;
    214. x++;
    215. x--;
    216. x = +y;
    217. x = -y;
    218. // 关系操作符与逻辑操作符:
    219. f(x > y);
    220. f(x >= y);
    221. f(x < y);
    222. f(x <= y);
    223. f(x == y);
    224. f(x != y);
    225. //- f(!x);
    226. //- f(x && y);
    227. //- f(x || y);
    228. // 按位操作符:
    229. x = ~y;
    230. x = x & y;
    231. x = x | y;
    232. x = x ^ y;
    233. x = x << 1;
    234. x = x >> 1;
    235. x = x >>> 1;
    236. // 复合赋值:
    237. x += y;
    238. x -= y;
    239. x *= y;
    240. x /= y;
    241. x %= y;
    242. x <<= 1;
    243. x >>= 1;
    244. x >>>= 1;
    245. x &= y;
    246. x ^= y;
    247. x |= y;
    248. // 类型转换:
    249. //- boolean bl = (boolean)x;
    250. char c = (char)x;
    251. byte b = (byte)x;
    252. short s = (short)x;
    253. long l = (long)x;
    254. float f = (float)x;
    255. double d = (double)x;
    256. }
    257. void longTest(long x, long y) {
    258. // 算术操作符:
    259. x = x * y;
    260. x = x / y;
    261. x = x % y;
    262. x = x + y;
    263. x = x - y;
    264. x++;
    265. x--;
    266. x = +y;
    267. x = -y;
    268. // 关系操作符与逻辑运算符:
    269. f(x > y);
    270. f(x >= y);
    271. f(x < y);
    272. f(x <= y);
    273. f(x == y);
    274. f(x != y);
    275. //- f(!x);
    276. //- f(x && y);
    277. //- f(x || y);
    278. // 按位操作符:
    279. x = ~y;
    280. x = x & y;
    281. x = x | y;
    282. x = x ^ y;
    283. x = x << 1;
    284. x = x >> 1;
    285. x = x >>> 1;
    286. // 复合赋值:
    287. x += y;
    288. x -= y;
    289. x *= y;
    290. x /= y;
    291. x %= y;
    292. x <<= 1;
    293. x >>= 1;
    294. x >>>= 1;
    295. x &= y;
    296. x ^= y;
    297. x |= y;
    298. // 类型转换:
    299. //- boolean bl = (boolean)x;
    300. char c = (char)x;
    301. byte b = (byte)x;
    302. short s = (short)x;
    303. int i = (int)x;
    304. float f = (float)x;
    305. double d = (double)x;
    306. }
    307. void floatTest(float x, float y) {
    308. // 算术操作符:
    309. x = x * y;
    310. x = x / y;
    311. x = x % y;
    312. x = x + y;
    313. x = x - y;
    314. x++;
    315. x--;
    316. x = +y;
    317. x = -y;
    318. // 关系操作符与逻辑操作符:
    319. f(x > y);
    320. f(x >= y);
    321. f(x < y);
    322. f(x <= y);
    323. f(x == y);
    324. f(x != y);
    325. //- f(!x);
    326. //- f(x && y);
    327. //- f(x || y);
    328. // 按位操作符:
    329. //- x = ~y;
    330. //- x = x & y;
    331. //- x = x | y;
    332. //- x = x ^ y;
    333. //- x = x << 1;
    334. //- x = x >> 1;
    335. //- x = x >>> 1;
    336. // 复合赋值:
    337. x += y;
    338. x -= y;
    339. x *= y;
    340. x /= y;
    341. x %= y;
    342. //- x <<= 1;
    343. //- x >>= 1;
    344. //- x >>>= 1;
    345. //- x &= y;
    346. //- x ^= y;
    347. //- x |= y;
    348. // 类型转换:
    349. //- boolean bl = (boolean)x;
    350. char c = (char)x;
    351. byte b = (byte)x;
    352. short s = (short)x;
    353. int i = (int)x;
    354. long l = (long)x;
    355. double d = (double)x;
    356. }
    357. void doubleTest(double x, double y) {
    358. // 算术操作符:
    359. x = x * y;
    360. x = x / y;
    361. x = x % y;
    362. x = x + y;
    363. x = x - y;
    364. x++;
    365. x--;
    366. x = +y;
    367. x = -y;
    368. // 关系操作符与逻辑操作符:
    369. f(x > y);
    370. f(x >= y);
    371. f(x < y);
    372. f(x <= y);
    373. f(x == y);
    374. f(x != y);
    375. //- f(!x);
    376. //- f(x && y);
    377. //- f(x || y);
    378. // 按位操作符:
    379. //- x = ~y;
    380. //- x = x & y;
    381. //- x = x | y;
    382. //- x = x ^ y;
    383. //- x = x << 1;
    384. //- x = x >> 1;
    385. //- x = x >>> 1;
    386. // 复合赋值:
    387. x += y;
    388. x -= y;
    389. x *= y;
    390. x /= y;
    391. x %= y;
    392. //- x <<= 1;
    393. //- x >>= 1;
    394. //- x >>>= 1;
    395. //- x &= y;
    396. //- x ^= y;
    397. //- x |= y;
    398. // 类型转换:
    399. //- boolean bl = (boolean)x;
    400. char c = (char)x;
    401. byte b = (byte)x;
    402. short s = (short)x;
    403. int i = (int)x;
    404. long l = (long)x;
    405. float f = (float)x;
    406. }
    407. }

    注意 boolean 类型是有限制的。我们只能赋予它 true 和 false 值,并测试它是真还是假,但不能将 boolean 值相加,或对 boolean 值执行其他任何运算。
    在 char、byte 和 short 中,你可以看到算术操作符对数据类型的提升效果。对这些类型进行任何算术运算,都会获得一个 int 结果,如果想把这个结果赋给原来的类型,则必须显式地进行类型转换(窄化转型可能会造成信息丢失)。对于 int 值则不需要进行类型转化,因为所有数据都已经是 int 类型的了。但不要误以为一切都是安全的,如果对两个足够大的 int 数值执行乘法运算,结果可能会溢出。下面这个示例展示了这一点:

    // operators/Overflow.java
    // 惊讶吧!Java允许溢出
    
    public class Overflow {
      public static void main(String[] args) {
        int big = Integer.MAX_VALUE;
        System.out.println("big = " + big);
        int bigger = big * 4;
        System.out.println("bigger = " + bigger);
      }
    }
    /* 输出:
    big = 2147483647
    bigger = -4
    */
    

    这里编译器不会有错误提示或警告信息,运行时也不会出现异常。
    对于 char、byte 或者 short,复合赋值并不需要类型转换。尽管它们都会做类型提升,并获得与直接算术运算相同的结果。而省略类型转换肯定使代码更简洁了。

    除 boolean 类型以外,任何基本类型都可以转换为其他基本类型。再次提醒,当某种类型转换成一种较小的类型时,你必须了解窄化转型的效果,否则可能会在类型转换过程中不知不觉地丢失了信息。