一、 Java中的变量
1.1 字面值的概念
字面值是内存中的一块空间,这块空间存放有值,并且这个值是有类型的。如:在内存中的某个空间存放着100的值,类型是整型。在内存的另一个空间存放着true,代表真,是布尔类型。
例子:字面值举例
public class VariableTest01 { public static void main(String[] args){ // 整型字面值 System.out.println(100); // 字符串类型字母值 System.out.println("Hello Java"); // 浮点型字面值 System.out.println(3.14); // 布尔型字面值 System.out.println(true); } } |
程序执行时,在内存中会分配四块空间,用来保存上面四个类型的值,如下图:
字面值就是内存中的一块空间,有值有类型。但是要注意:只有字面值是无法被重用的,使用完成后便成为垃圾,如下例子。
例子:字面值不能重用
public class VariableTest02 { public static void main(String[] args){ // 内存开辟一块空间,存放整型值100 System.out.println(100); // 内存又开辟一块空间,用来存放整型值100 System.out.println(100); } } |
如果想让字面值重用,需要一个变量指向字面值的内存地址,通过变量使保存在内存中的字面值重用。
1.1 变量
变量是内存中的一块区域,有四个基本属性:变量名称,数据类型,存储单元和变量值
变量名:合法的标识符
变量的数据类型:可以是基本类型或引用类型
存储单元:存储单元大小是由数据类型决定的,如:int 为4个字节32 位
变量值:在存储单元中放的就是变量值(如果是基本类型放的就是具体值,如果是引用类型放的是内存地址,如果null,表示不指向任何对象)
图:字面值和变量的关系
1.1.1 变量的声明与赋值
在Java中,定义一个变量需要为变量指定类型。语法格式如下。
变量类型 变量名称; |
为变量赋值采用等号的方式,如下格式。
变量名称 = 值; |
下面的例子是先声明一个变量,然后在给变量赋值。
例子:变量的声明与赋值
public class VariableTest03 { public static void main(String[] args){ // 声明一个整型的变量i int i; // 为变量i赋值100 i = 100; // 声明一个字符串类型的变量lesson String lesson; // 为字符串变量lesson赋值java lesson = "Java"; // 通过变量访问内存中的值,并且可以重复使用内存中的值 System.out.println(i); // 重复使用内存中的值 System.out.println(i); // 同上 System.out.println(lesson); } } |
注意:声明一个变量,相当于在内存中为这个变量分配了一块空间,并且将这个空间的类型也同时定义了(什么类型的变量只能赋给相同类型的值,否则编译不能通过)。并为这块空间起名为变量名。变量赋值是将一个特定的值存储在这块空间,所以,可以认为变量就是内存中的一块空间,这个空间有类型,可以存储相同类型的值。并且通过变量可以重复利用内存中的值。
声明变量的同时可以赋值,并且变量可以重新赋值,但同名的变量不能声明两次。否则编译不能通过。
例子:变量的在局部只能声明一次,但可以多次赋值
public class VariableTest04 { public static void main(String[] args){ // 声明变量并赋值 int i = 100; // 通过变量访问内存中的值 System.out.println(i); // 为变量重新赋值 i = 200; // 内存中的值发生改变,值为200 System.out.println(i); // 声明同名变量,编译不能通过 // error //int i = 300; // 声明同名变量,编译不能通过 // error //String i = "zhangSan"; } } |
在一个作用域中,如果声明同名的变量,Java虚拟机会无法识别并区分变量,因为变量代表一块内存空间,所以编译时就会提示警告信息。
图:同一作用域中声明同名变量时,Java虚拟机无法区分变量
但是在两个不同的作用域中是可以声明同名的变量的,如下例子。
例子:在不同的作用域中可以声明同名的变量,Java虚拟机根据作用域区分同名变量,并且变量的生命周期和作用域相同
public class VariableTest05 { public static void main(String[] args){ // 声明变量并赋值 int i = 100; // 将变量值输出到控制台 System.out.println(i); // 调用方法 method01(); } // 静态方法 public static void method01(){ // 声明变量并赋值 int i = 200; // 使用变量 System.out.println(i); } } |
在不同的方法体中各自声明了变量i并赋值,编译通过,因为两个变量i在不同的作用域中,相当于两个不同的空间,互相不影响。
图:不同作用域内的变量和作用域相关,并且变量的生命周期和作用域相关
在方法体中声明的变量,只有赋值后才可以使用,如果只是声明变量在没有赋值的情况下使用变量,会提示警告信息,编译不能通过,如下例子。
例子:局部变量必须赋值后才能访问,可以先声明,在使用前再赋值
public class VariableTest06 { public static void main(String[] args){ // 声明变量并赋值 int i; i = 100; // 局部变量只有赋值后才可以使用 System.out.println(i); // 声明了一个字符串变量但没有赋值,只是分配了一块空间,空间没有值 String userName; // 局部变量没有赋值就直接使用会提示警告信息,编译不能通过 // error //System.out.println(userName); } } |
注意:说的是方法体内的变量,必须赋值后才可以使用,如果没有赋值就使用,编译时不能通过的。
1.1.1 变量的作用域
作用域是变量的有效范围,也就是变量的可访问范围。在一个作用域中声明的变量,只能在当前域中可以访问,下面例子说明。
例子:变量的作用域是变量的有效访问范围
public class VariableTest07 { public static void main(String[] args){ // 当前方法中声明的变量,只能在当前方法中才可以访问 int i = 100; // 访问当前作用域内声明的变量,没有问题 System.out.println(i); // 变量userName在方法method01中声明的,所以变量的作用域是method01 // 只有在method01方法中才可以访问,所以,编译不能通过 // error //System.out.println(userName); } public void method01(){ // 变量userName的作用域在此方法中,只有在此方法中才可以访问 String userName = "zhangsan"; } } |
作用域的范围可以理解为一对大括号内的范围,只要在大括号内,变量声明后的任何位置都可以访问变量。
1.1.2 在类体内声明变量
在类体中可以声明方法,在方法体内可以存在Java语句。但在类体中不能直接书写Java语句,这是Java语法。如果在类体中书写Java语句,编译不能通过,如下面的例子。
例子:在类体中,只能在方法中才能存在Java语句
public class VariableTest08 { // 类体 // 在类体中可以声明方法,但不能直接书写Java语句,编译不能通过 // error //System.out.println("Hello Java!"); public static void main(String[] args){ // 方法体 // 在方法体中,可以书写一行到多行Java语句 System.out.println("Hello Java!"); } } |
在类体中不能存在Java语句,但是可以声明变量,声明的变量作用域是整个类体。但是需要注意的是,在方法体内声明的变量叫局部变量,而在类体中声明的变量不叫全局变量,分为两种类型的变量,一是成员变量,另一类是静态变量。所以在此类中声明的变量如果是成员变量那么在所有的成员方法中都可以访问,如果是静态变量在所有的静态方法中都可以访问,如下例子。
例子:成员变量和静态变量的访问特点
public class VariableTest09 { // 声明成员变量 int i = 100; // 声明静态变量 static int j = 1000; // 成员方法 public void method01(){ // 成员方法可以直接访问成员变量 System.out.println(i); // 成员方法也可以访问静态变量 System.out.println(j); } // main方法是静态方法,有static关键字修饰 public static void main(String[] args){ // 静态方法不能直接访问成员变量 // error //System.out.println(i); // 静态方法可以直接访问静态变量 System.out.println(j); } } |
在静态方法中只能访问静态变量,如果想访问成员变量需要创建对象,通过对象进行访问,后面的章节会详细说明。在成员方法中可以访问成员变量,也可以访问静态变量,因为静态变量属于类,也就是说属于所有成员的,所以在成员方法中可以访问静态变量。
另外,在Java中如果成员变量和局部变量同名,基于就近原则,在方法中访问的是局部变量。变量不能同名声明是针对同一个作用域来说的,成员变量或静态变量和局部变量本不在同一个域中,所以可以同名,下面例子说明。
例子:变量的就近原则
public class VariableTest10 { // 声明静态变量 static int i = 100; public static void main(String[] args){ // 声明局部变量 int i = 200; // 静态变量和局部变量同名,基于就近原则,访问的是局部变量,输出200 System.out.println(i); } } |
1.1.3 其他的局部变量
除方法体内声明的变量是局部变量外,还有其他的形式,如方法中的参数,for循环中的表达式等等其他形式的局部变量。如方法中的参数的作用域是方法体内,for循环中的条件表达式中声明的变量只在循环体内是可见的,如下例子。
例子:局部变量的可见范围是大括号内
public class VariableTest11 { public static void main(String[] args){ // for循环,变量i是局部变量,只能在循环体内可以访问 for(int i = 0;i < 10;i++){ // 循环体是变量i的作用域 System.out.println(i); } // 访问循环的局部变量,编译不能通过 // error //System.out.println(i); } public void method01(int i){ // 方法的参数i是局部变量,作用域是方法体内,在方法体内可直接访问 System.out.println(i); } } |
1.1.4 变量的分类
在Java中,变量可以分为三类,成员变量、静态变量和局部变量。在方法体中声明的变量叫做局部变量。包括形式参数列表和其他形式的变量,如for循环。在类体中声明的变量可以是成员变量,也可以是静态变量,如下面例子。
例子:成员变量在堆内存,是对象相关的,静态变量是类级别的,在方法区内存,而局部变量只在栈区
public class VariableTest12 { // 成员变量 int id = 101; // 成员变量 String userName = "zhangsan"; // 静态变量 static String country = "china"; public static void main(String[] args){ // 局部变量 int person = 200; // i是局部变量 for(int i = 0;i < 10;i++){ System.out.println(i); } // 调用静态方法 VariableTest12.method01(10); } // 参数i是局部变量 public static void method01(int i){ // 局部变量 i = 10; System.out.println(i); } } |
图:静态变量、成员变量和局部变量在内存中的位置
对于局部变量,必须声明并赋值后才可以使用,但是成员变量和静态变量不需要赋值就可以使用,因为系统会为没有赋值的成员变量和静态变量赋默认值,如下例子。
例子:静态变量和成员变量不用手动赋值也可以直接使用,因为成员变量和局部变量在内存中的位置不同
public class VariableTest13 { public static int i; public static short s; public static byte b; public static long l; public static float f; public static double d; public static boolean bo; public static char c; public static void main(String[] args){ System.out.println("i=" + i); System.out.println("s=" + s); System.out.println("b=" + b); System.out.println("l=" + l); System.out.println("f=" + f); System.out.println("d=" + d); System.out.println("bo=" + bo); System.out.println("c=" + c); } } |
控制台输出:
i=0 s=0 b=0 l=0 f=0.0 d=0.0 bo=false c=_ // \u0000 |
一、 Java中的数据类型
在Java总共有两种数据类型,一种是基本类型另一种是引用类型,基本类型有八种,不是基本数据类型的都是引用类型。
2.1 基本数据类型
在Java中有八种基本数据类型,每种类型占用内存的空间大小不同,表示的数值范围也不同。如下表。
变量类型 |
细类 |
类型名称 |
占用内存范围 |
取值范围 |
默认值 |
数值类型 |
整数型 |
byte |
一个字节 |
-2^7~2^7 - 1 -128~127 |
0 |
short |
二个字节 |
-2^15~2^15 - 1 -32768~32767 |
0 |
||
int |
四个字节 |
-2^31~2^31 – 1 -2,147,483,648~ 2,147,483,647 |
0 |
||
long |
八个字节 |
-2^63~2^63 -1 -9,223,372,036,854,775,808~ 9,223,372,036,854,775,807 |
0 |
||
浮点型 |
float |
四个字节 |
1.4E-45~3.4028235E38 |
0.0 |
|
double |
八个字节 |
4.9E-324~1.7976931348623157E308 |
0.0 |
||
字符类型 |
char |
两个字节 |
0~2^16 – 1 0~65535 |
\u0000 |
|
布尔类型 |
boolean |
一个字节 |
true/false |
false |
2.2 字符编码
我们知道,计算机只能识别二进制,并且所有的数据在机器上都是以0、1的形式存储,如:byte类型的10在机器上的存储的形式是什么呢!因为byte类型占用一个字节,也就是八个bit,所以byte类型的10在底层存储的是00001010,如果short类型的10在底层存储的是00000000 00001010,而int类型的10在底层存储的形式是00000000 00000000 00000000 00001010。在八种基本数据类型中,byte、short、int、long、float和double都是数值类型,只要按照二进制和十进制的转换规则来回进行转换就可以了。boolean类型的值只有true和false,在底层也是由1和0来区分的。而char类型占用两个字节,因为char类型支持的不仅仅是字母数字,包括中文,所以Java中的char类型采用的是unicode编码。
编码 |
描述 |
ASCII 字符编码 |
采用一个字节编码,主要针对英文编码 |
ISO-8859-1 |
有称latin-1,是国际化标准或组织ISO 制定的,主要为了西欧语言中的字符编码,和ASCII兼容 |
GB2312/GBK/GB18030 |
主要是汉字编码,三种编码从容量上看是包含关系 |
unicode |
Unicode 统一了全世界上的所有文字编码,unicode 有几种实现:UTF-8,UTF-16,UTF-32 |
char类型变量的声明,如下例子。
例子:char类型变量声明原则
public class CharTest01 { public static void main(String[] args){ // 不能采用双引号声明字符类型,必须采用单引号声明字符类型 // error //char c1 = "a"; // 声明变量并赋值a字符 char c2 = ‘a‘; // 字符类型赋值只能是单个的字符,不能是字符串 // error //char c3 = ‘ab‘; // 在Java中,字符a对于的编码是97 char c4 = 97; // 输出a System.out.println(c4); // 字符变量赋值a char c5 = ‘a‘; // 输出a System.out.println(c5); } } |
注意:字符编码方式是将文字和其他现实中的字符与计算机可以识别的二进制数值之间的转换规则。如果字符采用的编码和解码方式不一致,就会出现乱码。常用到的例如a的ASCII编码为97,A编码为65,0为48。
char类型用两个字节来存储一个字符,采用的是unicode编码方式。
例子:char类型采用两个字节表示字符,可以表示中文
public class CharTest02 { public static void main(String[] args){ // char类型占用两个字节来存储一个汉字, char c1 = ‘好‘; // 输出好 System.out.println(c1); // 好的Unicode编码为\u597d char c2 = ‘\u597d‘; // 同样输出好 System.out.println(c2); } } |
2.3 数据类型详解
2.3.1 整数类型
Java中的整数类型有byte、short、int和long,在内存中分别占用的字节数为1、2、4、8。所以取值范围不同。
Java 语言中整数型有三种表示方法,默认的是十进制
1.十进制 10
2.八进制,八进制必须以0开头,如:010
3.十六进制,十六进制必须以0x开头,如:0x10
例子:Java中的数值类型表示
public class DataTypeTest01 { public static void main(String[] args){ // 在Java中默认是十进制 int i1 = 10; // 八进制的10 int i2 = 010; // 十六进制的10 int i3 = 0x10; System.out.println(i1); // 10 System.out.println(i2); // 8 System.out.println(i3); // 16 } } |
通常情况下采用的是十进制。
需要注意的是在Java中整数类型默认为int 类型,如果变量类型不是int类型,会发生类型转换,如果是int类型向long类型转换会发生自动类型转换,值的精确度不会损失,如果大类型的变量向下转换为short类型或byte类型,需要强制类型转换,并且会损失精确度,但是如果整型值没有超过short、byte和char的取值范围,可以直接赋值,下面通过几个例子详细说明。
第一个例子说明的是int类型和long类型之间的转换,要知道,Java中整型字面值的类型默认是int类型,所以当声明一个变量时,如果变量的类型是int型是不存在类型转换的,如果声明的变量类型是long,虽然不需要手动进行类型转换,实际上还是进行了自动类型转换,从int型转换成long类型,因为是从小类型转换成大类型,值的精确度不会损失,所以这种情况下,我们通常会忽略转换过程,如下例子。
例子:int类型与long类型之间的类型转换
public class DataTypeTest02 { public static void main(String[] args){ // 没有类型转换,字面值为整型默认为int类型 int i = 1000; // 进行了类型转换,从小类型到大类型,自动类型转换,没有精度损失 long l = 100; // 进行了自动类型转换,从小类型到大类型,没有精度损失 l = i; // int类型上限值,没有类型转换 i = 2147483647; // 超出了int类型的上限值,不能赋值,编译不能通过 // error //i = 2147483648; // 从int类型转换到long类型,自动类型转换,没有精度损失 l = 2147483647; // 因为字面值超出了int类型的上限,所以编译不能通过 // 也说明了Java中字面值为整型的默认为int类型 // error //l = 2147483648; // 字面值后面添加L,说明字面值的类型是long类型,没有自动类型转换 // 是普通的赋值 l = 2147483648L; // 将int类型的字面值赋值给long类型变量,有自动类型转换精度没有损失 l = 123; // 将大类型赋值个小类型,需要强制类型转换,因为没有进行强制类型转换 // 所以编译不能通过 // error //i = l; // 将大类型转换成小类型,需要强制类型转换,精度有损失,要谨慎使用 i = (int)l; // 将字面值后添加L,字面值的类型成为long类型而不是默认的int类型 // 所以没有类型转换,是普通的赋值 l = 456L; // 原理同上,从大类型到小类型需要强制类型转换,所以编译不能通过 // error //i = l; // 原理同上,将大类型转换成小类型需要进行强制类型转换 // 但是精度会有损失,要谨慎使用 i = (int)l; } } |
第二个例子是byte类型变量的赋值。
例子:byte类型变量的赋值与类型转换
public class DataTypeTest03 { public static void main(String[] args){ // 没有类型转换,是普通的赋值 int i = 100; // 从int类型的字面值赋值给byte类型,从大类型转换成小类型, // 注意:虽然是从大类型转换成小类型,但不需要进行强制类型转换 // 因为字面值50没有超出byte类型的取值上限,所以可以直接赋值 // 注意:因为字面值没有超出byte类型的取值上限,所以没有类型转换 byte b = 50; // 从大类型到小类型,需要进行强制类型转换,所以编译不同通过 // error //b = i; // 从大类型int转换成byte类型,需要进强制类型转换,精度会有损失 b = (byte)i; // 字面值127没有超出byte类型的取值上限,所以可以直接赋值 // 没有类型转换 b = 127; // 字面值128超出了byte类型的取值上限,所以编译不能通过 // error //b = 128; // 超出了byte类型的取值上限,需要强制类型转换,精度会损失,谨慎使用 b = (byte)128; // 从小类型到大类型,自动类型转换,没有精度损失 long l = 60; // 从大类型到小类型,必须强制类型转换,所以编译不能通过 // error //b = l; // 从long类型赋值byte类型,需要强制类型转换,精度有损失,谨慎使用 b = (byte)l; // 自动类型转换,没有精度损失 l = 1000; // 字面值1000已经超过了byte类型的取值上限,需要强制类型转换 // 但精度有损失,谨慎使用 b = (byte)l; } } |
第三个例子是short类型变量的赋值。
例子:short类型变量的赋值与类型转换
public class DataTypeTest04 { public static void main(String[] args){ // 没有类型转换,是普通的赋值 int i = 100; // 从int类型的字面值赋值给short类型,从大类型转换成小类型, // 注意:虽然是从大类型转换成小类型,但不需要进行强制类型转换 // 因为字面值没有超出short类型的取值上限,所以没有类型转换 short s = 1000; // 从大类型到小类型,需要进行强制类型转换,所以编译不同通过 // error //s = i; // 从大类型int转换成short类型,需要进强制类型转换,精度会有损失 s = (short)i; // 字面值32767没有超出short类型的取值上限,所以可以直接赋值 // 没有类型转换 s = 32767; // 字面值32768超出了short类型的取值上限,所以编译不能通过 // error //s = 32768; // 超出了short类型的取值上限,需要强制类型转换,精度会损失,谨慎使用 s = (short)32768; // 从小类型到大类型,自动类型转换,没有精度损失 long l = 500; // 从大类型到小类型,必须强制类型转换,所以编译不能通过 // 虽然字面值500没有超过short类型的取值上限 // error //s = l; // 从long类型赋值short类型,需要强制类型转换,精度有损失,谨慎使用 s = (short)l; // 自动类型转换,没有精度损失 l = 1000000; // 字面值1000000已经超过了short类型的取值上限,需要强制类型转换 // 但精度有损失,谨慎使用 s = (short)l; } } |
第四个例子是char类型变量的赋值。char类型是字符类型,但底层存储的是二进制数值,每个字符对应一个数值编码,char类型的取值范围是从0~65535,默认值是\u0000,是二进制的0,如a的ASCII码是97。
例子:char类型变量的赋值与类型转换
public class DataTypeTest05 { public static void main(String[] args){ // 没有类型转换,是普通的赋值 int i = 300; // 从大类型到小类型,但不需要强制类型转换,因为字面值没有超过char // 类型的取值范围,所以可以直接赋值 char c = 97; // 从大类型到小类型,需要强制类型转换,编译不能通过 //c = i; // 强制类型转换可能带来精度损失 c = (char)i; // 从int类型赋值给char类型,没有超出char类型的取值上限 // 不需要强制转换,直接赋值 c = 65535; // 字面值超出char类型的取值上限,编译不能通过,需要进行强制类型转换 //c = 65536; // 强制类型转换,损失精度 c = (char) 65536; // 自动类型转换 long l = 1000000; // 需要强制类型转换 //c = l; // 强制类型转换,损失精度 c = (char)l; } } |
2.3.2 浮点类型
Java语言中浮点类型包括float和double类型,float类型占用四个字节,double类型占用八个字节。注意:Java中的浮点类型默认为double。与整型中的int类型相似。double类型精度要高于float类型。下面通过一个例子说明。
例子:float和double类型变量的赋值与类型转换
public class DataTypeTest06 { public static void main(String[] args){ // 在Java中,浮点数默认为double类型,所以没有类型转换,是赋值运算 double d = 3.14; // 字面值是double类型的值,大类型到小类型需要强制类型转换, // 编译不能通过,需要强制类型转换 // error //float f = 3.14; // 强制类型转换,但可能损失精度 float f = (float)3.14; // 同上,大类型到小类型需要强制类型转换,编译不能通过 // error //f = d; // 强制类型转换,可能损失精度 f = (float)d; // 可以将字面值后面添加F,表示值的类型是float,不需要强制类型转换 // 只是赋值运算 f = 3.14F; } } |
2.3.3 布尔类型
Java中的布尔类型只能取值true或false,不能取其他的值。主要用在逻辑运算和条件控制语句中。下面通过例子说明。
例子:布尔类型变量的赋值与类型转换
public class DataTypeTest07 { public static void main(String[] args){ // 布尔类型只能赋值true或false,编译不能通过 // error //boolean b = 1; // 赋值true boolean b1 = true; // 赋值false boolean b2 = false; // 通过三目表达式返回true或false并赋值给变量b3 boolean b3 = 3 > 2 ? true : false; // 分支语句,如果b3为true,执行打印任务 if(b3){ System.out.println("b3=" + b3); } } } |
2.3.4 总结
1.在Java中基本类型可以相互转换,但boolean 类型不能转换成其他类型
2.类型转换分为自动类型转换和强制类型转换
3.自动类型转换发生在小类型向大类型转换
自动类型转换的顺序从左到右,如下:
byte |
short |
int |
long |
float |
double |
char |
|||||
一个字节 |
两个字节 |
四个字节 |
八个字节 |
四个字节 |
八个字节 |
5.byte、short、char 之间计算不会互相转换,首先先转换成int,下面通过例子说明。
例子:当byte、short和char类型变量进行计算时,要先转换成int类型在进行计算,所以结果是int类型
public class DataTypeTest08 { public static void main(String[] args){ // int类型的字面值没有超过byte类型的取值范围,自动类型转换 byte b1 = 10; // 同上 short s1 = 20; // 先转换成int类型,在运算,结果是int类型 int i = b1 + s1; // 声明两个变量 byte b2 = 30; byte b3 = 40; // 结果是int类型,从大类型到小类型需要强制类型转换,编译不能通过 // error //byte b4 = b2 + b3; // 没有超过byte类型的取值范围,直接赋值 byte b5 = 30 + 40; // 同上 short s2 = 20; short s3 = 50; // 同上,编译不能通过,需要强制类型转换 // error //short s4 = s2 + s3; //没有超过short类型的取值范围,直接赋值 short s5 = 20 + 50; } } |
6.强制类型转换是当容量大的类型转换成容量小的类型时,必须进行强制类型转换,但是要注意精度损失
7.只要不超出范围可以将整型值直接赋值给byte,short,char
8.在多种类型混合运算过程中,首先先将所有数据转换成容量最大的那种类型,然后再进行运算,下面通过例子说明。
例子:多种数值类型变量进行计算时,所有类型的变量先转换成其中最大的类型然后进行计算,结果的类型是最大的数值类型
public class DataTypeTest09 { public static void main(String[] args){ // 声明四个不同类型的变量 byte b = 10; short s = 20; int i = 200; long l = 500; // 四个变量中最大类型是long,所以所有参加运算的变量首先转换成 // 最大类型,然后在进行运算,结果是long类型,需要强制类型转换 // 编译不能通过 // error //int sumI = b + s + i + l; // 同上,编译不能通过 //short sumS = b + s + i + l; // 结果是long类型,直接赋值 long sumL = b + s + i + l; } } |
2.3.5 作业
判断下面例子中,哪些赋值语句编译不能通过,哪些赋值语句编译通过,并说出理由。
public class DataTypeTest10 { public static void main(String[] args) { byte b1 = 1000; byte b2 = 20; short s1 = 1000; short s1 = 1000; int i1 = 1000; long d = i1; int i2 = d; int i3 = (int)d; int f = 10/3; long l1 = 10; int i4 = l1/3; int i5 = (int)l1/3; byte b3 = (byte)(int)l1/3; byte b4 = (byte)(int)(l1/3); byte b5 = (byte)l1/3; byte b6 = (byte)(l1/3); short s2 = (short)(l1/3); short s3 = 10; byte b7 = 5; short s4 = s3 + b7; short s5 = (short)(s3 + b7); int i6 = s3 + b7; char l = ‘a‘; System.out.println(l); System.out.println((byte)l); int m = l + 100; System.out.println(m); } } |