目录
一、字面常量
所谓的常量,就是程序运行期间,固定不变的量,我们就称为常量。
常见的字面常量可分为以下6种:(前五种字面常量与C语言相似,空常量会在后面的文章中介绍到)
1. 字符串常量
2. 整型常量
3. 浮点型常量
4. 字符常量
5. 布尔常量:true/fslse
6. 空常量:null
二、数据类型
Java中的数据类型可以分为两大类:基本数据类型和引用数据类型。
本文只对基本数据类型进行介绍,引用数据类型(包括数组、字符串、类、接口、枚举、String等)会在之后的文章中详细讲述。
基本数据类型可以分为四类:整型、浮点型、字符型(char)、布尔类型(boolean)。而整型又可以分为字节型(byte)、短整型(short)、整型(int)、长整型(long);浮点型可以分为单精度浮点型(float)、双精度浮点型(double)。下面这个表格就可以很清晰地看出来。
数据类型 | 关键字 | 内存占用 | 范围 |
字节型 | byte | 1字节 | -128 ~ 127 |
短整型 | short | 2字节 | -32768 ~ 32767 |
整型 | int | 4字节 | -2^(31) ~ 2^(31) - 1 |
长整型 | long | 8字节 | -2^(63) ~ 2^(63) - 1 |
单精度浮点型 | float | 4字节 | 有范围,但是一般情况下不会关注 |
双精度浮点型 | double | 8字节 | 有范围,但是一般情况下不会关注 |
字符型 | char | 2字节 | 0 ~ 65535 |
布尔型 | boolean | 没有明确规定 | true 和 false |
对于基本数据类型,有以下几点需要注意:
1. 无论是在16位系统还是在32位系统中,int都是占4个字节,long都是占8个字节
2. 整型和浮点型都是带有符号的
3. 整型类型默认为int型;浮点型默认为double型
4. 布尔型其内存占用并没有明确规定,有可能是1字节(byte),也有可能是1比特(bit)
三、变量
与C语言相同的,在Java中,变量就是能够改变内容的来量。其定义变量的语法格式也和C相同,都是:
数据类型 变量名 = 初始值
1. 整型变量
整型变量
在前面学C语言的时候我们知道,在定义变量的时候如果不给其赋初始值,则会自动赋成随机值。而在Java中不一样,如果在定义变量的时候不对其进行初始化,在使用的时候很可能会报错(这点就可以体现出Java相较于C语言安全性的提升),这时候还可进行“弥补”的就是在使用前再设置初值,这样也是不会报错的,但是正常来说还是建议定义的时候直接把初始值给赋上,这样也可以避免一些不必要的错误。
public class TestDemo {
public static void main(String[] args) {
//方式一:在定义时给出初始值
int a=10;
System.out.println(a);
//方式二:在定义时没有给初始值,但使用前必须设置处置
int b;
b=10;
System.out.println(b);
//int型变量所能表示的范围:
System.out.println(Integer.MIN_VALUE);
System.out.println(Integer.MAX_VALUE);
}
}
关于整型变量的注意点:
1. Java中int无论在何种系统下都是4个字节(区别:C语言中则不一定都是4字节)->进而表现出Java良好的跨平台性
2. 变量在使用之前必须要赋初值,否则编译报错->安全性的体现
3. 比较推荐使用上述方法一的定义方式,如果没有合适的初始值,则可以设置为0
4. 在给变量设置初始值的时候,值不能超过int的表达范围,否则会导致溢出(区别:C语言中则可能是会发生截断)->进而又可以体现出Java相对于C语言安全性的提升
5. int的包装类型为Integer(可以理解为是int的加强版本)
长整型变量
长整型变量的基础介绍与整型变量是相似的,这里就直接写出代码。
public class TestDemo {
public static void main(String[] args) {
//long定义变量的三种情况:
long a=10;
long b=10L;
long c=10l;
//long型变量所能表示的范围:
System.out.println(Long.MIN_VALUE);
System.out.println(Long.MAX_VALUE);
}
}
关于长整型变量的注意点:
1. 长整型变量的初始值后可加L或者l,但是推荐加L
2. 长整型无论在哪个系统下都是占8个字节
3. 在给变量设置初始值的时候,值不能超过long的表达范围,否则会导致溢出,情况与上面的情况类似
4. long的包装类型为Long(可以理解为是long的加强版本)
短整型变量
对于短整型变量,其实与上面的整型和长整型情况类似,但是要注意的是:
1. short在任何系统下都是占2个字节
2. short的包装类是Short(可以理解为是short的加强版本)
字节型变量
简单地介绍以下字节型变量,对于字节型变量有几点是需要记住的:
1. byte在任何系统下都是占用1个字节
2. byte值的范围是在-128~127
3. byte的包装类是Byte(可以理解为是byte的加强版本)
以上的四种变量都是整型变量,他们对应的字节大小各不相同,所以其值的范围也是不一样的,所以就需要根据自己的需求来选择合适大小的整型变量,避免报错或者内存占用过大等问题。
2. 浮点型变量
双精度浮点型
Java中的浮点型与C语言中的浮点型大致相同,以下是两段代码:
public class TestDemo {
public static void main(String[] args) {
//代码一:
double a=1.0;
double b=2.0;
System.out.println(a/b);
//代码二:
double c=1.1;
System.out.println(c*c);
}
}
关于双精度浮点型变量的注意点:
1. double在任何系统下都是占8个字节
2. 在代码一中,可以推出Java中,int除以int的值仍会是int(会直接舍弃小数部分);如果想要得到小数部分,就需要使用double类型
3. 在代码二中,可以推出double类型的内存与在整型类型中的存储方式不同,而是遵守IEEE 754内存布局(这一点和C语言是完全一样的),尝试使用有限的内存空间表示可能无限的小数,势必会存在一定的精度误差,因此,浮点数是一个近似值,而不是一个精确值
4. double的包装类是Double(可以理解为是double的加强版本)
单精度浮点型
对于单精度浮点型float来说,与双精度浮点型中的内存布局形式是相同的,但是由于表示的数据精度范围较小,一般在工程上用到的浮点数都优先考虑到double类型,不太会去也不推荐去使用float以及float的包装类型Float,所以这里不对单精度浮点型做详细的解释说明。
3. 字符型变量
public class TestDemo {
public static void main(String[] args) {
char c1='a';
char c2='1';
char c3='蔡';
System.out.println(c1);
System.out.println(c2);
System.out.println(c3);
}
}
通过上面短短的几行代码,很快就可以看出与C语言的区别:Java中的字符是可以存放中文的。计算机中字符本质上是一个整数,在C语言中使用ASCII表示字符,而Java中使用Unicode表示字符,所以一个字符占用两个字节,这样表示的字符种类也就可以更多,这其中就可以包含一个中文字符了(中文字符占良字节)。
char的包装类是Character(可以理解为是char的加强版本)
4. 布尔型变量
public class TestDemo {
public static void main(String[] args) {
boolean b=true;
System.out.println(b);
}
}
使用布尔型变量需要注意的几点:
1. boolean类型的变量只有两种取值,true表示真,false表示假
2. Java中的boolean类型和int类型不能互相转换,不存在1表示true,0表示false,所以下面的这点代码是错误的:
public class TestDemo {
public static void main(String[] args) {
boolean value=true;
System.out.println(value+1);
}
}
3. JVM(Java虚拟机)规范中,并没有明确规定boolean占几个字节,也没有专门用来处理boolean的字节指令,但是有说boolean数组会被JJVM识别为字节数组,也就是占一个字节(8bit)。但如果boolean不做数组的话,有可能就是占一个bit位
4. boolean的包装类是Boolean(可以理解为是boolean的加强版本)
四、类型转换
public class TestDemo {
public static void main(String[] args) {
int a=10;
long b=100L;
b=a; //编译成功
a=b; //编译失败
}
}
正如上面的两段不同类型之间的变量互相赋值的代码,如果是在C语言中,则这两个代码都可以编译通过,其中的第二个在赋值的时候会发生截断;而在Java中,因为安全性的提升,导致第二个代码编译的时候会报错。
那么,在Java中,当参与运算数据类型不一致时,就会进行类型转换。Java中类型转换主要分为两类:自动类型转换(隐式)和强制类型转换(显式)。
1. 自动类型转换(隐式)
所谓的自动类型转换,就是代码不需要经过任何处理,在代码编译的时候,编译器会自动进行处理。
其特点是:数据范围小的转换为数据范围大的时候会自动进行。比如下面几个例子:
public class TestDemo {
public static void main(String[] args) {
int a=10;
long b=100L;
b=a; //编译成功,编译器会自动将a提升为long类型
a=b; //编译失败,long范围比int范围大,会有数据丢失,不安全
float c=3.14F;
double d=5.12;
d=f; //编译成功,b编译器会将f转换为double类型
f=d; //编译失败,double范围比float范围大,会有数据丢失,不安全
byte e1=100; //编译成功,100没有超过byte的范围,编译器隐式将100转换为byte
byte e2=257; //编译失败,257超过了byte的数据范围,有数据丢失
}
}
2. 强制类型转换(显式)
所谓的强制类型转换,就是当进行操作的时候,代码需要经过一定的格式处理,不能自动完成的。
其特点是:数据范围大的到数据范围小的。比如下面几个例子(上面代码中几个不能通过编译的代码应该写成这样):
public class TestDemo {
public static void main(String[] args) {
int a=10;
long b=100L;
a=(int)b;
float c=3.14F;
double d=5.12;
f=(float)d;
byte e=(byte)257;
}
}
最后,关于类型转换还需要注意到的几个点:
1. 不同数据类型变量之间赋值,表示范围范围更小的类型能隐式转换成范围大的类型
2. 如果需要把范围大的类型赋值给范围小的,需要进行强制类型转换,但是可能会发生精度丢失等现象
3. 将一个字面值常量进行赋值的时候,Java会自动针对数字范围进行检查
4. 强制类型转换不一定能成功,不相干的类型不能互相转换,就比如下面这样:
public class TestDemo {
public static void main(String[] args) {
int a=10;
boolean flag=true;
a=flag; //编译失败,类型不兼容
flag=a; //编译失败,类型不兼容
}
}
五、类型提升
1. 第一种情况(常见)
对于不同类型的数据之间互相运算时,数据类型小的会被提升到数据类型大的。比如下面这个例子:
public class TestDemo {
public static void main(String[] args) {
int a=10;
long b=20;
int c=a+b; //编译失败
long d=a+b; //编译成功
}
}
int类型和long类型同时存在做运算的时候,int会被提升为long,运算的结果也是long类型。
2. 第二种情况
但是也不是所有类型提升都是这个样子的,对于short,byte这种比4字节小的类型,会先提升成4字节之后,再做运算,就如下面的例子:
public class TestDemo {
public static void main(String[] args) {
byte a=10;
byte b=20;
byte c=a+b; //编译失败
int d=a+b; //编译成功
}
}
就像上面byte和byte都是相同类型,但是还会出现编译错误,那是因为计算a+b的时候,会先将a和b都提升成int类型,再进行计算。这样做的目的是因为计算机的CPU通常都是按照4字节为单位从内存中读写数据,所以为了硬件方便,这些低于4个字节的类型都会先提升为4字节。
六、字符串类型
本文只介绍最基本的字符串类型(基础认识),详细的内容会在之后的文章中出现。
我们知道,在C语言中是没有一个东西能够专门且直接来定义一个字符串的,而Java中出现了一个专门来定义字符串类型的——String类。如下所示:
public class TestDemo {
public static void main(String[] args) {
String s1="hello";
String s2="world";
System.out.println(s1);
System.out.println(s2);
System.out.println(s1+s2); //s1+s2表示将s1和s2拼接起来
}
}
这里就可以引出:字符串拼接是用+号将其连接起来的,比如:
public class TestDemo {
public static void main(String[] args) {
int a=10;
int b=20;
System.out.println("a="+a+" b"+b);
System.out.println("a+b="+(a+b)); //计算在字符串后面要加括号
System.out.println(a+b+"=a+b"); //计算在字符串前面不用加括号
}
}
接下来,介绍一下字符串和整型数字之间的转换(经常会使用到):
1. int转成String
这里有两种方法:
public class TestDemo {
public static void main(String[] args) {
int n=10;
//方法一:
String str1=n+"";
//方法二:包装类
String str2=String.valueof(n);
}
2. String转成int
对于String转int是不能用该字符串减去一个空字符串的,只能够使用包装类的方法:
public class TestDemo {
public static void main(String[] args) {
String str="100";
int n=Integer.parseInt(str);
}
}