目录
- 变量要先赋值后使用
- 计算并赋值运算符
- 数据类型自动转换
- 强制类型转换和数字溢出
- 从数值计算溢出理解程序员和编程语言
1. 变量要先赋值后使用
- 变量要先赋值后使用
- 不给变量赋值代表什么
- 不赋值就使用会怎么样
public class AssignFirst { public static void main(String[] args) { int a; int b = a + 1; } } // 输出 AssignFirst.java:5: 错误: 可能尚未初始化变量a int b = a + 1; ^ 1 个错误
也就是我们在使用 a 之前必须对 a 初始化,如果对 a 声明但不使用可以无需声明。
赋值之后就可以正常使用了。
public class AssignFirst { public static void main(String[] args) { int a = 1; int b = a + 1; } }
2. 计算并赋值运算符
- 计算并赋值运算符
- 作用是为了让代码更简洁。比如 a = a +10,可以简化为 a += 10
- +=
- -=
- /=
- *=
- %=
- &=
- ^=
- |=
- <<=
- >>=
- >>>=
public class Demo { public static void main(String[] args) { int a = 16; a >>= 1; System.out.println("one,A. moves to the right:>>>" + a); a >>= 2; System.out.println("two,A. moves to the right:>>>" + a); } }
运行结果如下:
one,A. moves to the right:>>>8 two,A. moves to the right:>>>2
/* * @Author: AI悦创 * @Date: 2020-09-23 10:22:46 * @Last Modified by: aiyuechuang * @Last Modified time: 2020-09-23 10:26:59 */ public class CalcAndAssign{ public static void main(String[] args){ int a = 16; a >>= 2; System.out.println(a); // 4 a *= 9; System.out.println(a); // 36 } }
3. 数据类型自动转换
- 自动类型转换
- 不会出现问题的类型转换,编程语言可以做自动类型转换,比如低精度的数字向高精度的数字转换。
- 自动类型转换可以发生在算数运算,也可以发生在赋值。
- 数值精度顺序:double>float>long>int>short>byte
- char 可以转换为 int
- char 可以转换为 int
- 虽然同样是两个 byte,但是因为 char 是无符号数,值域超出了 short 可以表示的范围,所以不可以自动转为 short。
public class AutoConvert { public static void main(String[] args) { int intVal = 99; long longVal = intVal; long longVal2 = intVal + 1; System.out.println(longVal2); // 100 float floatVal = 11.32f; double doubleVal = floatVal; double doubleVal2 = floatVal * 2; System.out.println(doubleVal2); // 22.639999389648438 doubleVal = longVal; // 99 doubleVal = intVal; // 99 floatVal = intVal; // 99 floatVal = longVal; // 99 char ch = 'A'; // 65 // char ch2 = 'a'; // 97 int chNum = ch; int chNumCalc = ch + 10; System.out.println(chNumCalc); // 75 System.out.println(ch); // A System.out.println(chNum); // 65 } }
比如上面的 char 自动转成 int,所谓来而不往非礼也,那我们也可以是 int 转换到 char 这里就涉及到 强制数据类型转换。
补充:
public class Demo { public static void main(String[] args) { int a = 99; int b = 5; System.out.println(a / b); } }
运行结果如下:
19
显然不是我们所需要的结果,故修改代码如下:
public class Demo { public static void main(String[] args) { int a = 99; double b = 5; System.out.println(a / b); } }
运行结果如下:
19.8
如上进行了自动的数据类型转换,进行了低精度转换到高精度。
public class Demo { public static void main(String[] args) { int num1 = 99; int num2 = 5; System.out.println(num1 + num2); System.out.println(num1 - num2); int num3 = 99; double num4 = 5; System.out.println(num3 + num4); System.out.println(num3 - num4); } }
上面其实已经演示了在运算的时候进行了数据类型的自动转换,接下来就主要演示一下发生在赋值时的数据类型自动转换,例程如下:
// double>float>long>int>short>byte // Java 会自动把低精度转换到高精度 public class Demo { public static void main(String[] args) { int a = 99; double b = a; System.out.println(a); // 99 System.out.println(b); // 99.0 } }
4. 强制数据类型转换
- 强制类型转换
- 可能出现问题的类型转换,需要使用强制类型转换,比如高精度数值向低精度数值转换。
- 强制类型转换也是操作符
- 语法是用小括号括起来的目标类型放在被转换的值前面
- 强制转换会造成数据精度丢失
- 数值溢出
- 数值计算一旦溢出,结果将失去其原有意义。比如,两个正数会加出负数。
- 要对能够处理的值有大概的估计。
4.1 强制类型转换
public class ForceConvert { public static void main(String[] args) { int intVal = 99; long longVal = 19999; intVal = longVal; // intVal = (int) longVal; // 小括号,然后括号里面填写目标类型。 // 它会阻止你,但你可以像如下使用强制转换,告诉程序,不要阻止我,我我已经知道 float floatVal = 11.32f; double doubleVal = 3344556.789; floatVal = (float) doubleVal; int a = 65; char b = (char) a; } }
运行结果如下:
ForceConvert.java:5: 错误: 不兼容的类型: 从long转换到int可能会有损失 intVal = longVal; ^ 1 个错误
我们把上面的错误代码注释掉,把 intVal = (int) longVal; 取消注释。
代码如下:
public class ForceConvert { public static void main(String[] args) { int intVal = 99; long longVal = 19999; // intVal = longVal; intVal = (int) longVal; // 小括号,然后括号里面填写目标类型。 // 它会阻止你,但你可以像如下使用强制转换,告诉程序,不要阻止我,我我已经知道 float floatVal = 11.32f; double doubleVal = 3344556.789; floatVal = (float) doubleVal; int a = 65; char b = (char) a; } }
接下来我们来看看:强制转换会造成数据精度丢失
public class ForceConvertValueLoss { public static void main(String[] args) { int intVal = 99; long longVal = 5555555555555L; intVal = (int) longVal; // long 是八位,int 是四位, // 而强制类型转换就截取后面的四位, // 好巧不巧后面四位的开头是 1 所以是负数。 System.out.println(intVal); float floatVal = 11.32f; double doubleVal = 1234567890.123456; floatVal = (float) doubleVal; System.out.println(floatVal); System.out.println(doubleVal); } }
-2132125469 1.23456794E9 1.234567890123456E9
4.2 数值溢出
数值计算一旦溢出,结果将失去其原有意义。比如,两个正数会加出负数。
要对能够处理的值有大概的估计。
public class CalcValueLoss { public static void main(String[] args) { int intVal = 2000000000; System.out.println(intVal + intVal); }
由上面的代码可以知道,这两个数字相加肯定是会超过 int 的范围,但是 java 不会帮我自动转换的。
它是一个静态的规则,int + int 得出来的就是 int 不会替你变成 long 之类的,int + long 它会帮你自动转换到 long 。
所以,无论你算出来的结果是多少,有没有溢出它就是 int 。
运行结果:
-294967296
由上面的结果可知,其实这不是我们想要的。所以,我们在表达一些数据的时候,对操作的值要有一个合理的期待。
比方说:你哪怕用一个 byte 来表示第几月都是没有问题的。因为月最多就 12个月,byte 有128也是足够了。(表示一个月第几号也是够的)但实际开发中,我们也是用 int 来表示的。因为我们后面深入理解之后,你用 byte 也是不会节省多少内存。所以,这个时候我们使用 int 表示这个数就可以了。
对于那个银行存款用 int 表示可能就不是很合适了,为什么呢?
有些人小目标很多,有可能几百个小目标,那这几百个小目标就超出了 int 的范围了。
这个时候,我们就要考虑,如果做的是跟钱相关的话,那你就可以考虑用 long 用 double 来表示这个 money。(当然,这个肯定不是最优解咯)
以上就是给大家举个例子,大家在做数据处理的时候就要对要处理的数据有个大概的估计,然后再选一个合理的数据类型来处理它。
5. 从数值计算溢出理解程序员和编程语言责任的分界线
我们要对哪些是需要我们程序员来完成,哪些是编程语言来完成的,我需要有个分界线。
5.1 编程语言的作用
- 编程语言负责按照语法执行
- 编程语言负责和计算机交互
5.2 程序员的任务
- 程序员负责理解问题
- 程序员负责理解程序,并将问题转换为程序
- 编程语言不负责解决问题,程序员才负责解决问题