☀️写在前面
最近刚开始学习Java,有些东西和c的差别还是挺大的,还有些新知识,借此写篇博客记录总结过渡一下。
文章目录
1️⃣初识Java
当创建了一个项目和源文件时,首先映入眼中就是一个类,因为在Java的世界中一切皆对象。
main方法
public class Test{
public static void main(String[] args){
System.out.println("Hello,Java");
}
}
如上的代码就是最简单的一个Java程序。
不同于c语言的是,c中的main方法一个项目只能有一个,而Java的main方法一个文件就能有一个。
Java程序的结构
通过上述代码,我们可以看到一个完整的Java程序的结构,Java程序的结构由如下三个部分组成:
- 源文件(扩展名为*.java):源文件带有类的定义。类用来表示程序的一个组件,小程序或许只会有一个类。类的内容必须包含在花括号里面。
- 类:类中带有一个或多个方法。方法必须在类的内部声明。
- 方法:在方法的花括号中编写方法应该执行的语句。
总结:类存在于源文件里面;方法存在于类中;语句存在于方法中。
运行Java程序
Java是一门半编译型、半解释型语言。
先通过javac命令编译程序把源文件进行编译,编译后生成的.class文件(二进制文件)是由字节码组成的平台无关、面向JVM的文件。
最后启动java命令让虚拟机来运行.class文件,此时JVM会将字节码转换成平台能够
理解的形式来运行。
2️⃣变量与类型
我们使用内存,就要合理划分空间使用,类型定义变量时就是在内存中分配空间,用该内存空间保存数据。
八大基本类型
整型(int)
定义变量格式:
//int 变量名 = 初始值
int num = 10;
注意事项:
- 默认值:
0
注意观察默认值要在类中定义变量观察,不能再主方法不初始化就使用变量。
public class Test {
static int x;
public static void main(String[] args) {
System.out.println(x);
}
}
- 一个整型变量的大小为4字节。
- 4 个字节表示的数据范围是
-2^31 -> 2^31-1
System.out.println(Integer.MAX_VALUE); // int 的最大值:2147483647
System.out.println(Integer.MIN_VALUE); // int 的最小值:-2147483648
- 和c语言不同的是java中没有无符号整型
长整型(long)
定义变量格式:
//long 变量名 = 初始值;
long num = 10L; // 定义一个长整型变量, 初始值写作 10l 也可以(小写的 L)
注意事项:
- 默认值:
0
- 使用 10 初始化也可以, 10 的类型是
int
,10L
的类型是 long, 使用10 L
比10 l
更好一些,因为大写的L
比小写的l
明显。 - 和c不同的是,
long
定义的变量的大小只有四个字节。在java中long
类型占8个字节。
表示的数据范围-2^63 -> 2^63-1
字节类型(byte)
定义变量格式:
//byte 变量名 = 初始值;
byte value = 0;
注意事项:
- 默认值:
0
- 字节类型表示的也是整数。 只占一个字节, 表示范围较小
( -128 -> +127)
。 - 字节类型和字符类型互不相干。
- 在进行IO编程时使用,文件输入输出网络传输都是用
byte
类型。
短整型(short)
定义变量格式:
//short 变量名 = 初始值;
short value = 0;
注意事项:
short
占用 2 个字节, 表示的数据范围是-32768 ~ 32767
- 这个表示范围比较小, 一般不推荐使用.
双精度浮点型(double)
定义变量格式:
//double 变量名 = 初始值;
double num = 1.0;
注意事项:
- 默认值:
0.0
- c和Java 中的 double 都是 8 个字节,内存布局遵守 IEEE 754 标准(和C语言一样)。
double num = 1.1;
System.out.println(num * num)
// 执行结果
1.2100000000000002
此时有精度丢失,因为尝试使用有限的内存空间表示可能无限的小数,势必会存在一定的精度误差。
如果想要输出结果无精度丢失,需要使用BigDecimal
类来解决。
解决代码:
import java.math.BigDecimal;
public class Test {
public static void main(String[] args) {
BigDecimal num = new BigDecimal("1.1");
BigDecimal result = num.multiply(num);
System.out.println(result);
}
}
//输出结果:
1.21
单精度浮点型(float)
定义变量格式:
//float 变量名 = 初始值;
float num = 1.0f; // 写作 1.0F 也可以
注意事项:
- 默认值:
0.0
float
类型在 Java 中占四个字节, 同样遵守 IEEE 754 标准. 由于表示的数据精度范围较小, 一般在工程上用到浮点数都优先考虑double
, 不太推荐使用float
。
字符类型(char)
定义变量格式:
//char 变量名 = 初始值;
char ch = 'A';
注意事项:
- 默认值:
\u0000(空格符)
- 计算机中的字符本质上是一个整数.。在 C 语言中使用 ASCII 表示字符(大小为1字节), 而 Java 中使用 Unicode 表示字符.。因此一个字符占用两个字节, 表示的字符种类更多, 包括中文等等。
例如可以仅用一个字符变量就可以保存一个汉字,在c中是不行的:
char ch = '呵';
System.out.println(ch);
//输出结果
呵
布尔类型(boolean)
定义变量格式:
//boolean 变量名 = 初始值;
boolean value = true;
注意事项:
boolean
类型的变量只有两种取值,true
表示真,false
表示假.- Java 的
boolean
类型和int
不能相互转换, 不存在1
表示true
,0
表示false
这样的用法。
而且在 if 和 while 的条件判断处,只能用布尔表达式,不能像c语言中用非 0 的整型或者指针进行判断。
这点和c语言很不一样,注意区别 boolean
类型有些 JVM 的实现是占 1 个字节, 有些是占 1 个比特位, 这个没有明确规定.
字符串类型
和上面的类型不同, String 不是基本类型, 而是引用类型.
定义变量格式:
//String 变量名 = "初始值";
String name = "zhangsan";
如果不进行初始化的默认值为null
字符串中的一些特定的不太方便直接表示的字符需要进行转义.
转移字符示例:
// 创建一个字符串 My name is "张三"
String name = "My name is \"张三\"";
常用的转义字符:
转移字符 | 解释 |
---|---|
\n | 换行 |
\t | 水平制表符 |
’ | 单引号 |
" | 双引号 |
\ | 反斜杠 |
字符串的 + 操作, 表示字符串拼接:
String a = "hello";
String b = "world";
String c = a + b;
System.out.println(c);
\\输出结果
hello world
还可以用字符串和整数进行拼接:
String str = "result = ";
int a = 10;
int b = 20;
String result = str + a + b;
System.out.println(result);
System.out.println("a = " + a + ",b = " + b);
输出结果:
当+
表达式中存在字符串的时候,都是执行字符串的拼接行为,将该类型转化为字符串类型。
总结:
3️⃣变量的命名规则
硬性要求:
- 一个变量名只能包含数字, 字母, 下划线
- 数字不能开头.
- 变量名是大小写敏感的. 即
num
和Num
是两个不同的变量.
注意: 虽然语法上也允许使用中文/美元符($
)命名变量, 但是强烈不推荐这样做.
软性要求:
- 变量命名要具有描述性, 见名知意.
- 变量名不宜使用拼音(但是不绝对).
- 变量名的词性推荐使用名词.
- 变量命名推荐小驼峰命名法, 当一个变量名由多个单词构成的时候, 除了第一个单词之外, 其他单词首字母都大写.
例如:
int maxValue = 100;
String studentName = "张三";
类-源文件命名:大驼峰
例如:ArrayTest
命名规则是从第一个单词就开始首字母大写。
包-项目命名
例如:java_11_19
命名规则是全小写,中间用下划线隔开。
4️⃣常量
字面值常量
0b10 //二进制字面值常量,十进制的2
10 // int 字面值常量(十进制)
010 // int 字面值常量(八进制) 由数字 0 开头. 010 也就是十进制的 8
0x10 // int 字面值常量(十六进制) 由数字 0x 开头. 0x10 也就是十进制的 16
10L // long 字面值常量. 也可以写作 10l (小写的L)
1.0 // double 字面值常量. 也可以写作 1.0d 或者 1.0D
1.5e2 // double 字面值常量. 科学计数法表示. 相当于 1.5 * 10^2
1.0f // float 字面值常量, 也可以写作 1.0F
true // boolen 字面值常量, 同样的还有 false
'a' // char 字面值常量, 单引号中只能有一个字符
"abc" // String 字面值常量, 双引号中可以有多个字符.
final 关键字修饰的常量
final int a = 10;
a = 20; // 编译出错. 提示 无法为最终变量a分配值
注意事项:
- c语言中是用
const
修饰常量. - 常量不能在程序运行过程中发生修改.
final
成员变量必须在声明的时候初始化或者在构造器中初始化,否则就会报编译错误。- 被声明
final
所以类型是不会转换
5️⃣理解类型转换
这里有c语言基础的,想要了解更多的可以看看下面一篇文章,可以了解一下思想。
🌀深入理解隐式类型转换🌀
Java 作为一个强类型编程语言, 当不同类型之间的变量相互赋值的时候, 会有教严格的校验.
int 和 long/double相互赋值
int a = 10;
long b = 20;
a = b; // 编译出错, 提示可能会损失精度.
b = a; // 编译通过.
int a = 10;
double b = 1.0;
a = b; // 编译出错, 提示可能会损失精度.
b = a; // 编译通过.
long
表示的范围更大, 可以将 int
赋值给 long
, 但是不能将 long
赋值给int
.
double
表示的范围更大, 可以将 int
赋值给 double
, 但是不能将 double
赋值给 int
.
结论: 不同数字类型的变量之间赋值, 表示范围更小的类型能隐式转换成范围较大的类型, 反之可能有精度损失,通过编译需要进行强制类型转换。
int 和 boolean 相互赋值
int a = 10;
boolean b = true;
b = a; // 编译出错, 提示不兼容的类型
a = b; // 编译出错, 提示不兼容的类型
结论:int
和 boolean
是毫不相干的两种类型, 不能相互赋值.
int字面值常量 给 byte 赋值
byte a = 100; // 编译通过
byte b = 256; // 编译报错, 提示 从int转换到byte可能会有损失
注意: byte 表示的数据范围是 -128 -> +127
,当将整型字面值赋给byte
时,Java会自动进行一些检查校验,当改值在byte
的保存范围之内,可以直接赋值,否则编译报错。
使用强制类型转换
int a = 0;
double b = 10.5;
a = (int)b;
int a = 10;
boolean b = false;
b = (boolean)a; // 编译出错, 提示不兼容的类型.
结论: 使用(强制类型)
的方式可以将 double
类型强制转成 int
. 但是
- 强制类型转换可能会导致精度丢失. 如刚才的例子中, 赋值之后, 10.5 就变成 10 了, 小数点后面的部分被忽略.
- 强制类型转换不是一定能成功, 互不相干的类型之间无法强转,例如
int
和boolean
.
5️⃣理解数值提升
int 和 long 混合运算
int a = 10;
long b = 20;
int c = a + b; // 编译出错, 提示将 long 转成 int 会丢失精度
long d = a + b; // 编译通过.
结论: 当int
和long
混合运算的时候,int
会提升成 long
, 得到的结果仍然是 long
类型, 需要使用 long
类型的变量来接收结果. 如果非要用 int
来接收结果, 就需要使用强制类型转换.
byte 和 byte 的运算
byte a = 10;
byte b = 20;
byte c = a + b;
System.out.println(c);
// 编译报错
Test.java:5: 错误: 不兼容的类型: 从int转换到byte可能会有损失
byte c = a + b;
^
结论: byte
和 byte
都是相同类型, 但是出现编译报错. 原因是, 虽然 a
和 b
都是 byte
, 但是计算 a + b
会先将 a
和 b
都提升成 int
, 再进行计算, 得到的结果也是 int
, 然后再赋给 c
,但是c
的类型还是byte
,所以就会出现上述错误.
这是由于计算机的 CPU 通常是按照 4 个字节为单位从内存中读写数据. 为了硬件上实现方便, 诸如 byte
和 short
这种低于4 个字节的类型, 会先提升成 int
, 再参与计算.
正确的写法:
byte a = 10;
byte b = 20;
byte c = (byte)(a + b);
System.out.println(c);
如果被final
修饰变量时
final byte a = 10,b = 20;
byte c = a + b;
System.out.println(c);
这里是不会报错的,因为a b
被final
修饰,所以类型是不会转换, 计算结果任然是byte,不需要强转。
6️⃣int 和 String 之间的相互转换
int 转成 String
int num = 10;
// 方法1
String str1 = num + "";
// 方法2
String str2 = String.valueOf(num);
String 转成 int
String str = "100";
int num = Integer.parseInt(str);
注意检查字符串中是否有除了数字之外的字符,如果有,在进行转换时会报错。
例如:
public class Test {
public static void main(String[] args) {
String str = "1234a";
int num = Integer.parseInt(str);
}
}
报错如下:
7️⃣运算符
这里只给出和c语言相较区别大一些地方,其他和c语言差不多。
1.
%
操作再 Java 中也能针对double
来计算,在c语言中只能对整数取余。
2. 由于 Java 是强类型语言, 因此对于类型检查较严格, 因此像 && 之类的运算操作数必须是boolean
.
3. c语言中右移(>>
)分为逻辑右移和算术右移,需要根据进行右移操作的数的类型判断是那种类型的右移。
无符号数对应逻辑右移,左边无脑用0
填充,右边丢弃。有符号数对应算术右移,左边用该数的符号位补齐。
而Java中对右移做了字面上的区分,补符号位的右移对应>>
,无符号右移对应>>>
。
8️⃣注释
Java中的注释主要分为以下三种
- 单行注释:// 注释内容(用的最多),一般用在方法内部。
- 多行注释:/* 注释内容*/(不推荐)
- 文档注释: /** 文档注释 */(常见于方法和类之上描述方法和类的作用),可用来自动生成文档
9️⃣关键字
关键字是 Java 中的一些具有特定含义的单词.
这是先了解下具体有啥,以后慢慢学。