一、字面常量
在我们使用Java进行数据的打印时,经常会用到这个语句:
System.out.println("Hello world!");
而当这个语句运行时,不论如何都会输出"Hello world!",所以"Hello world!"就是字面常量。
字面常量是指在代码中直接给出的,并且运行期间固定不变的量即为常量。
📌 Java支持以下几种字面常量:
📕 整数常量:整数常量可以是十进制、八进制或十六进制表示。例如:10、012、0xA。
📕 浮点数常量:浮点数常量可以是普通的十进制数表示,也可以使用科学计数法表示。例如:3.14、2.0E8。
📕 字符常量:字符常量是用单引号括起来的单个字符或转义序列。例如:'A'、'\n'。
📕 字符串常量:字符串常量是用双引号括起来的一串字符。例如:"Hello, World!"。
📕 布尔常量:布尔常量只有两个值,即true和false。
📕 null常量:null常量表示一个空引用。
(注意:Java中的布尔常量并非像C语言一样,分为"0"和"非0",而是仅仅使用true和false代表~)
📚 代码演示:
public class Main {
public static void main(String[] args) {
System.out.println(10);
System.out.println(3.14);
System.out.println('X');
System.out.println("Hello world!");
System.out.println(false);
}
}
运行代码:
📌 (上述代码中我们使用的是"println",其实除了它还有"printf"和"print")
📕 println:用于输出字符串或变量的值,并且自动换行;
例如:System.out.println("Hello World");
📕 printf:C语言中的输出函数,在Java中也有相应的使用方式;
例如:System.out.printf("Hello %s", "World");
📕 print:用于输出字符串或变量的值,但不会自动换行。
例如:System.out.print("Hello World");
二、数据类型
Java中数据类型主要分为两类:基本数据类型和引用数据类型。
由图我们可以知道,基本数据类型有"四类八种",四类分别指"整型,浮点型,字符型,布尔类型",八种分别指:
相较于C语言的数据类型,大部分都是没有变化的,除了布尔型的变化,我们还能发现:字符型char的大小从C语言中的1个字节,到java中就变成了2个字节。
而由此我们又能够引出字节的定义:
字节是计算机存储容量的基本单位,它表示存储的数据量。一个字节由8个二进制位(bit)组成。
📚 常见的字节单位包括:
1字节(B)= 8位(bit)
1千字节(KB)= 1024字节
1兆字节(MB)= 1024千字节
1千兆字节(GB)= 1024兆字节
1兆兆字节(TB)= 1024千兆字节
三、变量
① 变量的定义
在上面我们提到了"常量",也就是"不会变化的量"。而对应的,有"不变"就有"变",所以有些能够发生改变的量,如:财产,身高,成绩等,就被称作"变量"。
② 语法格式
定义变量的语法格式为:
数据类型 变量名 = 初始值;
📚 代码演示:
public class Main {
public static void main(String[] args) {
int a = 18;
double b = 3.14;
char c = 'a';
boolean d = true;
System.out.println("变化前:");
System.out.println(a);
System.out.println(b);
System.out.println(c);
System.out.println(d);
a = 999;
b = 6.28;
c = 'A';
d = false;
System.out.println("变化后:");
System.out.println(a);
System.out.println(b);
System.out.println(c);
System.out.println(d);
}
}
运行代码:
③ 整形变量
1. 整形变量
public class Main {
public static void main(String[] args) {
int a = 18;
System.out.println(a);
//(或者) int a;
// a = 18;
// System.out.println(a);
}
}
在Java中创建变量时必须进行初始化,如果定义后并未初始化,那么我们使用该变量时便会报错:
📌 需要注意的是:
📕 int不论在何种系统下都是4个字节。
📕 再给变量设置初始值时,值不能超过int的表示范围,否则会导致溢出(会类似上图一样报错)。
📕 int的包装类型为Integer。
这里引出两个话题:int的表示范围为多大?int的包装类型Integer有什么作用?
📚那么我们使用代码来查看一下:
public class Main {
public static void main(String[] args) {
System.out.println(Integer.MAX_VALUE);
System.out.println(Integer.MIN_VALUE);
}
}
运行代码:
由此我们便能观测出int型的表示范围,而其中MAX_VALUE和MIN_VALUE分别代表int型的最大与最小值。
而引出这两种边界值的就是int的包装类型Integer。
那么可能有的人就要问了:Integer和int有什么很大的区别吗?那这里我们将Integer替换成int又会发生什么呢:
我们可以看到,将Integer换成int后,代码就报错了,也就是说这个功能只有Integer能够实现~
也就是说:可以把Integer当作int的"plus"版本,它能够实现的功能更加丰富。(同时int具有的功能它也具有,比如初始化:)
public class Main {
public static void main(String[] args) {
int a = 10;
Integer b = 10;
System.out.println(a);
System.out.println(b);
}
}
运行代码:
2. 长整型变量
public class Main {
public static void main(String[] args) {
int a = 10;
long b = 10;
long c = 10L;
long d = 10l;
System.out.println(a);
System.out.println(b);
System.out.println(c);
System.out.println(d);
}
}
📌 需要注意的几个点:
📕 long长整型变量不论在哪个系统下都占8个字节。
📕 long长整型变量的初始值后面最好加个L或者l(一般写L,因为小写的l和1不好区分)。
📕 long长整型变量的表示范围非常大,有(-2^63 ~ 2^63 - 1)。
📕 long的包装类型为Long。
📚 那么我们尝试使用"Long"来表示一下长整型变量的表示范围:
public class Main {
public static void main(String[] args) {
System.out.println(Long.MAX_VALUE);
System.out.println(Long.MIN_VALUE);
}
}
运行代码:
个十百千万十万百万千万亿十亿百亿千亿万亿十万亿百万亿千万亿万万亿......数不清楚...
(这个数据范围远超 int 的表示范围,足够绝大部分工程场景使用)
3. 短整型变量
public class Main {
public static void main(String[] args) {
short a = 10;
System.out.println(a);
System.out.println(Short.MAX_VALUE);
System.out.println(Short.MIN_VALUE);
}
}
(short的包装类型为Short,所以这里直接使用啦)
📌 注意事项:
📕 short在任何系统下都占2个字节。
📕 使用不要超过范围。
📕 short包装类型为Short
4. 字节型变量
public class Main {
public static void main(String[] args) {
byte a = 10;
System.out.println(a);
System.out.println(Byte.MAX_VALUE);
System.out.println(Byte.MIN_VALUE);
}
}
📌 注意事项:
📕 byte在任何系统下都占1个字节。
📕 byte的范围很小,只有(-128 ~ 127)。
📕 byte的包装类型为Byte。
④ 浮点型变量
1. 双精度浮点型
public class Main {
public static void main(String[] args) {
double a = 12.5;
System.out.println(a);
System.out.println(Double.MAX_VALUE);
System.out.println(Double.MIN_VALUE);
}
}
(double的包装类型为Double)
在我们之前的学习中,我们知道C语言中使用整数除以整数,得到的只能是整数。(比如:5 / 2 = 2)
而此时我们不再使用C语言,而是使用Java,此时整数除以整数还会只能得到整数嘛?让我们尝试一下:
public class Main {
public static void main(String[] args) {
int a = 5;
int b = 2;
System.out.println(a/b);
}
}
不出所料,得到的还是2,那么再让我们将int型转换为double型:
public class Main {
public static void main(String[] args) {
double a = 5.0;
double b = 2.0;
System.out.println(a/b);
}
}
此时我们便能得到想要得到的2.5啦。
📚 接下来我们再看一段代码:
public class Main {
public static void main(String[] args) {
double a = 1.1;
System.out.println(a * a);
if(a * a == 1.21)
System.out.println("YES");
if(a * a != 1.21)
System.out.println("NO");
}
}
我们可以看到,答案并不是1.21,这是因为浮点数与整数在内存中的存储方式不同。
📌 注意事项:
📕 double在任何系统下都占8个字节。
📕 浮点数与整数在内存中的存储方式不同,不能单纯使用2^n的形式来计算。
📕 double的包装类型为Double。
📕 double类型的内存分布和C语言一样,使用有限空间表示可能无限的小数,必然会存在一定的精度误差,因此浮点数是近似值,并不是准确值。
2. 单精度浮点型
public class Main {
public static void main(String[] args) {
float a = 10.1f;
System.out.println(a);
}
}
注意:初始化float类型的变量时,需要在数据后加一个'f',或'F'。否则会被默认为double类型,而float类型无法接收double型变量,从而会导致报错。
📌 注意事项:
📕 float类型占4个字节。
📕 由于数据精度范围小,故一般很少使用float。
⑤ 字符型变量
首先我们在上面了解到,Java中的char类型与C语言中并不相同,Java中的char占两个字节。
📚 相应的,既然空间变大了,肯定也有它的优秀之处:
public class Main {
public static void main(String[] args) {
char a = 'a';
char b = 'B';
char c = '哈';
System.out.println(a);
System.out.println(b);
System.out.println(c);
}
}
(在C语言中,char型变量是无法做到存储中文汉字的,因为C语言中一个汉字的存储空间等于两个字符。而Java中的char大小为两个字节,也就说明它拥有存储汉字的能力~)
📚 同时,使用char关键字声明也能够存储整数,其意代表的是ASCII码对应的字符:
public class Main {
public static void main(String[] args) {
char a = 65;
char b = 97;
System.out.println(a);
System.out.println(b);
}
}
📌 注意事项:
📕 Java中使用 ' ' + 单个字母 的形式表示字符字面值。
📕 Java中char型变量可以存储整数,存储的是ASCII码值对应的字符。
📕 Java中char型变量可以存储中文汉字。
⑥ 布尔型变量
布尔类型所代表的只有两个:真(true) 或 假(false)。
public class Main {
public static void main(String[] args) {
boolean a = true;
boolean b = false;
if(a)
System.out.println(a);
if(b)
System.out.println(b);
}
}
📚 布尔型变量的用法有很多:
📕 使用布尔型变量来控制循环的执行:
boolean a = false;
while (!a) {
// 执行一些操作
// 如果满足某个条件,将a设置为true,结束循环
if (某个条件) {
a = true;
}
}
📕 判断语句中的条件表达式:
boolean a = false;
int age = 18;
if (age >= 18) {
a = true;
}
📕 布尔型变量还可以与逻辑运算符一起使用,形成更复杂的条件表达式:
boolean A = (number % 2 == 0);
boolean B = (number > 0);
boolean C = A && B; // 偶数且正数
boolean D = A || B; // 偶数或正数
boolean E = !A; // 非偶数
📌 注意事项:
📕 boolean 类型变量只有两种取值,true表示真,false表示假。
📕 Java中的 boolean 类型和 int 不能相互转换,不存在 1 表示 true,0表示 false 这样的用法。
📕 boolean 的包装类型为 Boolean。
四、字符串类型
我们知道,在C语言中是没有明确的字符串类型变量的,有的只是字符型char*指针变量存储字符串位置,和char型数组以存储多个字符的形式存储。
而在Java中就多了一个用于定义字符串类型:String。
📚 对于字符串的操作,有很多种类型:
📕 字符串与数字输出:(使用 ' + ' 进行衔接)
public class Main {
public static void main(String[] args) {
String str = "Hello, world!";
int length = str.length();
System.out.println(str);
System.out.println("Length: " + length);
}
}
(将一个字符串拼接上其他数据类型的数据,得到的结果就是一个字符串。)
比如:我们知道 a = 10,b = 20。此时我们想用字符串的形式打印:a + b = 30:
public class Main {
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println("a + b = "+a+b);
}
}
这样是正确的吗?让我们看一下结果:
欸?结果好像并不如我们所料想那般顺利,这是为何呢:
(因为,当println检测到 " " 时,便会开始将从这之后的数据直接变成字符串类型,而我们本用来运算"a + b = 30"的"a + b"就会被直接分别检测成"10" + "20",从而直接打印1020,而并非30)
解决方案:
方法一:(先计算数据,再引入字符串)
public class Main {
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println(a+b+" = a + b");
}
}
方法二:(使用括号,提高运算数据的优先级)
public class Main {
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println("a + b = "+(a + b));
}
}
📕 将 int 转换成 String:
方法一:(valueOf)
public class Main {
public static void main(String[] args) {
int num = 12345;
String str = String.valueOf(num);
System.out.println(str);
}
}
方法二:( + " " )
public class Main {
public static void main(String[] args) {
int num = 12345;
String str = num + "";
System.out.println(str);
}
}
运行代码:
📕 将 String 转换成 int:
public class Main {
public static void main(String[] args) {
String str = "12345";
int num = Integer.parseInt(str);
System.out.println(num);
}
}
(我们能看到,再次使用到了 Integer "包装类型",再一次证明了"包装类型"为原型的"plus"版本)
五、类型转换与提升
在之前学习C语言时,即便编写代码时有些错误的操作,也仍然能够进行数据的打印,但是Java相较于C语言会更加的严格,Java作为一个强类型编程语言,在不同类型之间进行赋值时,会有较为严格的校验。
Java中的类型转换可以分为两种:隐式类型转换和显式类型转换。
① 隐式类型转换(自动)
隐式类型转换是指将一个小范围的数据类型转换为一个大范围的数据类型,Java编译器会自动进行类型转换(所以也被称作自动类型转换),不需要用户明确指定。例如,将一个byte类型的变量赋值给int类型的变量。
byte -> short -> int -> long -> float -> double
📚 代码演示:
public class Main {
public static void main(String[] args) {
int a = 10;
long b = 20L;
b = a;
a = b;
}
}
当使用 b 来接收 a 时不会报错,因为 b(long) 相较于 a(int) 属于一个大范围的数据类型,能够完整无误的接收数据,故不报错;但当使用 a(int) 来接收 b(long) 时,就可能出现无法完整接受数据的情况(数据丢失)。
同样的:(使用 float 接收 double 报错)
(想要存储的数据超过该变量的范围:)
② 显式类型转换(强制)
显式类型转换是指将一个大范围的数据类型转换为一个小范围的数据类型,需要用户明确指定。在进行强制类型转换时,需要使用括号将目标类型括起来,并在变量前面加上强制转换的类型。例如,将一个int类型的变量赋值给byte类型的变量。
📚 代码演示:
public class Main {
public static void main(String[] args) {
int a = 10;
long b = 2147483648L;
a = (int)b;
System.out.println(a);
}
}
使用强制类型转换后,确实不报错了,但当我们运行时:
可以看到原来的"2147483648"变成了负数,这是因为将该数字存入int型时,其实是存不下的,最左边原本用来表达正负的二进制位,强制存储变成了1,从而变成了负数。
所以使用强制类型转换时,需要注意的是:要保证该类型能够存得下该数据。
📌 类型转换的注意事项:
📕 不同数字类型得变量之间赋值,表示范围更小的类型能隐式转换成范围较大的类型。
📕 如果需要把范围大的类型赋值给范围小的,需要强制类型转换,但是可能精度丢失。
📕 将一个字面值常量进行赋值的时候, Java 会自动针对数字范围进行检查。
📕 不相干的类型不能互相转换。
③ 类型提升
类型提升是指在表达式中,不同数据类型的操作数进行运算时,会自动将较小的数据类型提升为较大的数据类型,以保证计算的精度。
(类型提升顺序:byte、short、int、long、float、double由低向高转换。)
📚 代码演示:(int 与 long 之间的运算)
我们可以看到,使用int来接收a + b就会报错,而long就不会报错,这就是因为当 a + b 进行时,会将 int型 的a 转换成 long型,所以int型接收就会报错。
同样的:(float 与 double 之间的运算)
特别:byte 与 byte的运算:
public class Main {
public static void main(String[] args) {
byte a = 10;
byte b = 20;
byte c = a + b;
int d = a + b;
}
}
这段代码中,大家或许会觉得,int那行会报错吧?其实相反,byte c = a + b 会报错:
‘
(需要注意的是,由于byte在进行运算时会被提升为int,所以在用byte类型接收运算结果时需要进行强制类型转换。另外,由于byte是有符号类型,所以在进行运算时可能会出现溢出的情况,需要注意处理。)
📌 类型提升注意事项:
📕 不同类型数据混合运算,范围小的自动提升为范围大的。
📕 对于 short,byte 这类小于4字节的类型,会提升成4字节的 int 再运算。
那么关于Java中数据类型与变量的相关知识就为大家分享到这里啦,本人能力有限,如果有疏忽的地方,或者哪里讲的不够正确,还请各位在评论区多多指出,我也会吸取教训,多多学习的!那么我们下一期再见啦~