1.JavaSE之数据类型
1.1Java注释
Java中的注释分为三种
(1) 单行注释://
(2) 多行注释:/* 注释内容 */
(3) 文档注释:/** 文档注释 */ (常用于方法和类之上描述方法和类的作用,可以用来自动生成文档)
1.2Java中的标识符
Java语言中,对于变量,常量,函数,语句块也有名字,我们通常称为Java标识符。
(1) Java语言规定,标识符必须遵循以下规范:标识符必须以数字,大小写字母,下划线_,美元符号$组成。
例如,liu, _zhao, $wang等都是合法的标识符(但一般最好不要使用下划线和美元符号开头)。
(2) 标识符的第一个字符不能是数字,Java关键字不能当作Java标识符,一些特殊符号不能位于标识符中,如&,+,#,*,!以及一些中文特殊符号。
例如,567kan, Chen#,@meng ,if,class,.com都不是合法的标识符。
(3) Java语言严格区分大小写。
例如,Love和love是两个完全不同的标识符。
(4) 标识符的长度没有限制,但是不宜过长。
类名和接口名(大驼峰命名法UpperCamelCase)
每个单词的首字母大写。
例如,MyClass,YouInterface。
方法名,变量名,参数名(小驼峰命名法lowerCamelCase)
首字母小写,其余字母的首字母大写。
例如,sendMail,getName,setAge,myVariable。
常量名
基本数据类型的常量名由大写字母组成,字与字之间用下划线分隔。
例如,BUILDING_WINDOW_COLOR,SHOP_CUSTOMER_NUMBER。
1.3 Java中的关键字
关键字是Java特有的符号,用来表示特殊用途,用户不能重新定义这些符号。关键字由小写字母标示。
用于定义访问权限修饰符的关键字
private. public. protected
用于定义类,函数,变量修饰符的关键字
final. abstract. static. synchronized
用于定义类与类之间的关键字
extends. implements
用于定义建立实例及引用实例,判断实例的关键字
new. this. super. instanceof
用于异常处理的关键字
try. throw. thorws. catch. finally
用于包的关键字
package. import
其他修饰符关键字
native. strictfp. transient. Volatile. assert
关于Java关键字有以下几点说明:
(1) Java中有两个未使用的保留字,goto,const
(2) Java中有三个特殊含义的单词,true,false,null
(3) JDK1.4之后追加了assert关键字,JDK1.5之后追加了enum关键字
1.4 数据类型
Java数据类型分为两大类:基本数据类型和引用数据类型
######1.4.1 Java包括了8中常见的基本类型。
类型 | 关键字 | 字节数 | 取值范围 |
---|---|---|---|
布尔类型 | boolean | 1 | true flase |
字符类型 | char | 2 | \u0000~\uFFFF(0~65535) |
字节型 | byte | 1 | -128~127 |
短整形 | short | 2 | -32768~32767 |
整形 | int | 4 | -231~231-1 |
长整型 | long | 8 | -263~263-1 |
单精度浮点数 | float | 4 | -3.4E38~3.4E38 |
双精度浮点数 | double | 8 | -1.7E308~1.7E308 |
Java基本数据类型又分为4大类:布尔数据类型、字符类型、整数类型、浮点类型。
布尔类型
常用关键字boolean表示,在内存中占2个字节。
(1)布尔常量
布尔常量只有两个值,ture false。
(2)布尔变量的定义
使用关键字boolean来定义布尔变量。如定义布尔变量a1、a2、a3的格式如下:
boolean a1,a2,a3; //定义时没有给变量赋值,编译时由系统赋予默认值false
定义时给变量赋初值的格式如下:
boolean a1 = true, a2 = false; a3; //在同一行定义多个变量时,变量之间用逗号隔开
整型数据
整形数据分为四种:byte(字节型)、short(短整型)、int(整型)、long(长整型)
(1) byte
byte数据在内存中占一个字节。取值范围为-128~127。
byte a1 = 34,a2 = -12, a3; //定义时如果没有给变量赋值,编译时由系统给变量赋予默认值(0)
(2) short
short数据在内存中占2个字节。取值范围为-32768~32767
short a1 = 128, a2 = -666, a3; //默认值为0
(3) int
int数据在内存中占4个字节。取之范围为-231~231-1
int a1 = 32768, a2 = -129, a3; //默认值为0
(4) long
long 数据在内存中占8字节。取值范围-263~263-1
long a1 = 18, a2 = 777, a3 = 66552l;
表示long型常量的方法是在整数后面加字母l,例如 456l,789l。
(5) 常量表示方法
表示十进制的整数,如123(用十进制表示整数时不能为0);
表示八进制的整数,如567(首位为0,代表八进制数);
表示十六进制的整数,如0x9ABCD(首位为0x,代表十六进制数)
字符数据
字符数据类型常用关键字char表示,该数据类型在内存中占2个字节。
字符型使用char来表示,并且使用’ '来表示字符变量内容,并且可以与int相互转换
(1)字符型常量
一个字符常量用单引号括起来,如’A’、‘b’、‘c’、‘7’、‘爱’ 等都是字符型常量。
(2)字符型变量定义
使用关键字char来定义字符型常量。如定义char型变量a1、a2、a3的格式如下:
char a1,a2,a3; //默认值为\u0000
char型常量在内存中以正整数(int型)的方式保存,因此,最高位不是用来表示符号的。
范例:观察char与int型转换
char c = 'A';
int num = c;
System.out.println(num); //打印结果为65
大写字符(A-Z): 65 ~ 90;
小写字符 (a-z) : 97 ~ 122;
int型转为char型需要强制类型转换
范例:实现大写字母变小写字母(大写字母比小写字母小32个长度)
char c = 'A';
int num = 32 + c;
char x = (char) num;// int转char需要强制转换
System.out.println(x); //打印结果为a;
字符型数字(‘0’~’9’)与int数字(0~9)不同if(‘0’ == 0)一定是false;
(3) 转义字符
一些控制字符不能显示出来。下表表示了这些控制字符的含义。
控制字符 | 描述 |
---|---|
‘\n’ | 换行,将光标移到下一行的开始位置 |
‘\t’ | 将光标移到下一个制表符的位置 |
‘\r’ | 按Enter键,将光标移到当前行的开始,不是移到下一行 |
‘\\’ | 输出一个反斜杠 |
‘\’‘ | 输出一个单引号 |
‘\"’ | 输出一个双引号 |
(4) 字符型数据在内存中的表示
字符型数据类型在内存中以int型数据表示。如,字符常量’d’在内存中的值是100(ascii码)。
浮点类型
浮点型数据分为两种:float(单精度型)和 double(双精度型)。
-
float
float数据在内存中占4个字节。
(1) 常量
例如,567.789f、7889.3f、987.2f、777.00f。
书写单精度常量数据时,在数据最后必须加f,否则,表示的常量是双精度数据。
如,888.0是双精度数据。
(2) 变量定义
使用关键字 float 来定义单精度浮点型变量。默认值为0.0。
float a1 = 12.7f, a2 = 13.98f, a3;//a3没有被赋值,所以系统在编译时赋予默认值0.0
-
double
double数据在内存中占8个字节。
(1)常量
例如 5678.577d(d可以省略)、908.66、45678.009d 都是双精度常量。
(2)变量定义
使用关键字double来定义双精度型变量。
double a1 = 113.8764,a2 = -12.78d,a3;//默认值0.0
#####1.4.2 引用数据类型:
类、接口类型、数组类型、枚举类型、注解类型。
区别:
(1)基本数据类型在被创建时,在栈上给其划分一块内存,将数值直接存储在栈上。
(2)引用数据类型在被创建时,首先要在栈上给其引用(句柄)分配一块内存,而对象的具体信息都存储在堆内存上,然后由栈上面的引用指向堆中对象的地址。
基本数据类型char可以描述的只是单⼀的字符,现在要想描述多个字符,就必须利用字符串这一概念。需要说明的是 String不是基本数据类型,String是⼀个引⽤数据类型。
创建一个字符串对象的话,完全可以使用字面量的方法,字面量还是使用双引号
String str = "abc";
当我们使用字面量的方式创建字符串对象的时,java在内存中会开辟一个字符串缓冲区,也可以理解为字符串常量池。当我们真正创建字符串对象时,如这里的”abc” ,它就会到字符串常量池中查找这个对象有没有存在,如果没有,它就会新建这个对象, 然后把这个对象的地址引用赋值给我们声明的变量str。这时我们再声明一个变量
String str1 = "abc";
它又会到字符串常量池中寻找“abc”,这时候发现”abc” 这个对象已经存在,那它直接把常量池中存在的对象的地址赋值给声明的变量anotherString. 这就是字符串共享。
值得注意的是,字符串的共享也仅仅适用于字符串字面量,如果使用加号,或其它方法进行拼接形成的字符串,那就不一定在字符串常量池中了。如
String a = "hello";
String b = a + "world";
String c = "hello" + "world";
此时 c 肯定是在字符串常量池中的,因为java都是先编译再运行,一般编译时 c = “hello” + "world"都已经拼接好了,所以当程序运行的时候,它是一个字符串常量,要到常量池中查找。但是,b就不一样了,
b = a + “world”,因为a 是一个对象的引用,在栈中,在运行时会在堆上生成一个对象,虽然字符串b和c内容是一样的,但是地址确实不同的,此时就有
System.out.println(b == c); //打印结果为flase
如果用==进行判断,则比较的是两个变量所引用的对象的地址,而不是字符串内容是否相同。
当要进行字符串内容的比较时可以使用字符串中的方法 .equals() 此方法比较的两个字符串的内容是否相同。
1.5 数据类型转换
数据类型的转换包括两种:自动转换,强制转换。
1.5.1
-
数据类型精度排序
byte short int long float double
——————————————————>
低 ——》 高
- 自动转换
从低精度向高精度转换属于自动转换。
float xx = 200; //把整数200 转换为浮点数
这里将整数 200 赋给浮点型变量xx,是从低精度向高精度转换,系统自动进行。
如果输出xx的值,结果将是200.0。
//表达式中的数据转换 int h = 73; float y1 = 27.6f; double f = h+y1;
混合数据类型表达式h + y1包含两个不同类型的数据,即整数h 和单精度型数据y1。
在计算表达式之前,系统会自动将低精度的数据h转化成更高精度的float型数据,转换之后将两个数据进行求和,最后将结果数据(float型)转换为更高精度的double型数据并赋给变量f。
- 强制转换
从高精度向低精度转换属于强制转换。
(type)data //将数据data的类型转换为type型
data为需要转换的变量或者常量。type取值为 byte、short、int、long、float、double。
(1)赋值语句总的转换
int x = (int)567.78f
这里将float型数据567.78f赋值给整型变量x,是高精度向低精度的转换,需要在被转换的数据前使用目标类型转换符(int)。如果输出x的值,结果将是600。
(2)表达式中的数据转换
int h = 73; float y1 = 27.6f; int k = h+(int)y1;
混合数据类型表达式h+(int)y1包含两个不同类型的数据,即整数h和单精度浮点类型数y1。
在计算表达式之前,y1通过类型转换符(int)转换成低精度整型数据。
如果输出k的值,结果为100。
在使用强制类型转换的时候我发现了一个问题:关于转换之后精度有所损失。
double x = 3.141592654; float y = 0.0f; y = (float)x; System.out.println(y);//打印结果为3.1415927
float 保存小数点后六位,所以后面的小数会四舍五入进上来,而double类型则保存小数点后15位。
有一点值得注意,那就是当发生强制转换的时候,高精度向低精度转换,但是高精度的取值大于了低精度类型的取值范围,会发生什么?
int a; byte c; a = 130; c = (byte)130;//强制转换
此时我们将相对高精度的int型强制转换成了低精度的byte型,并且取值为130,但是我们知道byte占1个字节,取值范围也就是-128~127,我们a取值为130已经超出了byte的取值范围,程序会出错吗?
在idea的帮助下,我写了程序并且发现编译运行没有出错,而且打印出来的c的值为-126,我继续给a赋值为129,如我所愿打印出来的c的值为-127,可这是为什么呢?
因为,a = 130 是int类型,在内存中占4个字节,所以它的二进制数在内存中的表现形式是:
00000000 00000000 00000000 10000010 (128)
又因为计算机所有数据都是以补码的形式出现的,所以我们要算它的补码。
做截取为 原码1000 0010 最高符号为不变,其他位取反获得它的反码。
反码1111 1101 给反码加1 得补码。
补码1111 1110
计算时 最高符号位不计算 1x2^1 + 1x2^2 + 1x2^3 + 1x2^4 + 1x2^5 + 1x2^6 = -(2+4+8+16+32+64) = -126
所以发生强转之后,int类型的130 强转为 byte型的-126。