文章目录
一个简单的Java应用程序
我们先看一段最简单的Main方法
public class MainDemo {
public static void main(String[] args) {
System.out.println("hello world");
}
}
这段代码中,我们可以看到Java中最主要几个特点:
- Java代码是区分大小写的。
- 几个重要的关键字:
- public:访问修饰符
- class:Java总所有的内容都包含在这个class中。并且class关键字后,紧跟这个类的名称。
- {}:{}成为块,Java中任何方法的代码都用{}包括起来。
注释
首先上例子:
/**
* 文档注释
*/
public class MainDemo {
public static void main(String[] args) {
System.out.println("hello world");
// 单行注释
/*
* 多行注释
* 多行注释
* */
}
}
Java中主要是三种注释:
-
单行注释:只注释本行使用//,其注释内容从//开头,到本行末尾
-
多行注释:包含和在/**/中的所有内容都成为注释,可以跨越多行,但是多行注释不能进行嵌套。
以上两种注释,只能在项目中查看,无法生成doc文档。若要生成doc文档,需要使用文档注释
-
文档注释:使用/***/中的内容均为文档注释,后期可生成文档。详见第四章。
数据类型
Java是一种强类型的语言。意味这Java中,必须为每个变量定义一个类型。
Java中一共有8中基本数据类型:4种整数类型,2种浮点类型,1种字符类型,1种表示真假的布尔类型。
整数类型
类型 | 大小 |
---|---|
byte | 1字节 |
short | 2字节 |
int | 4字节 |
long | 8字节 |
浮点类型
浮点类型表示小数点可以浮动的实数。
类型 | 大小 |
---|---|
float | 4字节 |
double | 8字节 |
double的精度是float的两倍,所以double也被成为双精度。
⭐️定义float类型的变量,值的末尾必须加上f或者F,如果一个浮点类型的值末尾没有f或者F,会默认为double。此时使用float类型的变量接受会提示异常。
关于浮点类型的计算,遵循IEEE754规范,具体来说,有如下三种表示溢出和错误的情况:
- 正无穷大
- 负无穷大
- NaN(Not A Number)
字符类型
类型 | 大小 |
---|---|
char | 2字节 |
char类型的字面量需要使用单引号括起来。
布尔类型
boolean,只有两个值:
- true
- false(默认)
boolean不能与整型进行转换。
变量与常量
变量
就像上面提到的,Java是一门强类型的语言,所以必须为每一个变量都指定一个类型。
变量声明完成后,必须使用赋值语句对其进行初始化。
int a = 10;
常量
常量就是值不变的变量,在Java中,使用final关键字修饰的变量就是常量
final int B = 10;
常量在赋值之后,就无法改变了。
习惯上,常量名全部大写。
在开发中,常量不会定义在任何方法中,一般都在类或者接口最前面。
类常量
在Java开发中,我们经常需要定义一些可以全局使用的常量:
public static final int a = 10;
其中两个重要的关键字:
- public:一旦一个变量或者常量被public修饰,那么所有的类均可使用
- static:一旦一个变量或者常量被static修饰,那么它不在属于这个对象,而是属于这个类。
枚举
有时候,变量的取值在一个有限的集合中。比如:一年只有春夏秋冬四季,任何一个季节都在这四种之中。这种类型包含有限个命名的值。
我们使用枚举类型对这种有有限个值的变量进行定义,关键字为ENUM。
如何定义一个枚举类
先上一个枚举类的代码:
public enum EnumDemo {
CAT(1,"Tom"),MOUSE(2,"Jerry");
private Integer id;
private String name;
EnumDemo(Integer id, String name) {
this.id = id;
this.name = name;
}
}
⭐️枚举类答题上和一个普通的类定义方法差不多,但是还是有几个细节:
- 一般的类定义使用的是class关键字,枚举类使用的是enum关键字
- 一般类的构造器可以写也可以不写,枚举类构造器必须写,而且必须是私有构造器,所以private可以省略。
- 由于枚举类的实力就是有限的几个,所以在定义枚举类的最前面,必须将所有实例定义出来,并且实例之间使用逗号分隔,最后一个实例使用分号结尾.
- 在调用枚举类的时候,无需对枚举类进行实例化。直接使用枚举类名+"."进行调用即可。
运算符
Java中提供了一组丰富的算数和逻辑运算符:
- 算术运算符(+、-、*、/、%)
- 科学函数以及常量(Math工具类)
- 数值之间的转换
- 强制类型转换
- 结合赋值和运算符(+=、-=)
- 自增自减运算符(++、–)
- 关系和布尔运算符(==、!=、<、>、<=、>=、&、&&、|、||、三元操作符?:)
- 位运算符
- 括号与运算符级别
数值之间的转换
在开发过程中,我们经常需要将一种数据类型转换为另一种数据类型。
Java中合法的数据类型转换如下:
其中,实线为无精度损失的转换,虚线为损失精度的转换。
⭐️二元运算中的数据类型转换
当进行二元运算时,需要先将两个值转换成同一个类型再进行计算:
- 如果两个值之中有一个是double类型,另一个值会转换为double类型
- 否则,如果其中一个值是float类型,另一个值会转换为float类型
- 否则,如果其中一个值是long类型,另一个值会转换为long类型
- 否则,两个值均转换为int类型
强制类型转换
使用强制类型转换会损失精度,所以 需要手动强制操作。
double x = 9.997;
int nx = (int) x;
System.out.println(nx); // 9
在这个示例中,我们强行将double类型的x转换成int类型的nx。打印nx得到结果9,小数部分被舍去。
要进行强制转换,需要在括号中给出想要转换的目标类型。
字符串
在Java开发中,经常需要使用到字符串。但是Java并没有内置字符串类型,而是在标准Java类库中,提供了一个预定义类:String
String类型的变量,需要使用双引号括起来。
String str = "hello world";
字符串拼接
Java使用”+“对两个字符串进行拼接。
当一个字符串和另一个非字符串的值进行拼接时,非字符串的值会转换成字符串并进行拼接
String str = "hello world";
int a = 10;
System.out.println(str+a); // hello world10
不可变字符串
String并没有提供修改字符串中某个字符的方法。因为在Java中,String被设计成一个无法改变的字符串类型。
从String源码中可以看到,String由final修饰,使其不可更改。
public final class String
不可变字符串有一个最大的有点,就是可以让字符串实现共享。
检测字符串是否相等
检测字符串是否相等要使用equal方法,一定不要是用==去判断!
String str1 = "hello";
String str2 = "world";
System.out.println(str1.equals(str2));
空串和null串
空串和null串并不是同一个概念
String str3 = ""; // 空串
String str4 = null; // null
空串是一个Java对象,有自己的长度(0)和内容(空)
null表示目前没有任何对象与该变量相关联。所以null调用方法会导致空指针异常。
判断一个字符串是否为空串有两种方法:
- 使用equals方法与""进行内容比较
- 使用length方法判断字符串长度是否为0
System.out.println(str3.equals(""));
System.out.println(str3.length() == 0);
判断一个字符串是否为null,使用==进行判断
System.out.println(str4 == null);
字符串操作
关于字符出常规操作,可使用java.lang.String类中的方法
输入与输出
略
控制流程
在学习控制流程之前,需要理解块(block)的概念。
块(即符合语句),是由多条Java语句组成的语句,并用{}括起来。
块确定了变量的作用域,并且块可以嵌套。
嵌套的块中,无法定义相同名称的变量。
// 块结构
{
int x = 10;
{
int y = 10;
// int x = 11; 在嵌套的块中定义相同名称的变量会提示错误
}
}
条件语句
当我们需要判断一个条件是否为真时,执行一种代码;如果为假时,执行另一种代码。这时候我们可以用到条件语句。
它的范式为:
if(condition) statement
实例:
if(a > 0){
System.out.println("a大于0");
}else if(a == 0){
System.out.println("a等于0");
}else{
System.out.println("a小于0");
}
条件语句中,如果还有更多的判断条件,可以使用更多的else if进行判断。
循环
Java中,循环有三种:
- for循环
- while循环
- do while循环
for循环
当我们确定一个循环的循环次数的时候,可以使用for循环
for (int i = 0; i < 1000; i++) {
System.out.println(i);
}
在上面的实例中,我们使用了for循环将循环进行了1000次。
其中,int i 充当了一个计数器。i= 0我们设置了初始值,然后每次运行一次代码块中的内容,i自增1,直到1<1000,也就是i=999。
while和do while循环
两种循环基本相同,只有一个不同点:
- while循环会先进行判断,如果判断不通过,不会进行块中的内容
- do while不会先去判断,而是无论如何都会先执行一次块中内容,再进行判断。
int b = 0;
//while 循环
while (b < 0){
b++;
System.out.println(b);
}
// do while循环
do {
b++;
System.out.println(b);
}while (b<0);
从上面的实例中,我们看到,因为b=0,所以无论是while循环和do while循环都不满足条件。while循环并没有执行代码块中的内容,而do while循环直接先执行了一次.
鉴于do while会先执行一次代码块的特点,会出现一个很特别的情况:
int b = 0;
while (b > 0){
b++;
System.out.println(b);
}
do{
b++;
System.out.println(b);
}while (b>0);
上面这种情况,我们可以看到无论是while或者do while的判断语句都不满足条件,所以while的代码块不会执行。但是do while会限制性一次代码块,导致b从0变为1,满足了判断条件b>0,所以循环会无限执行下去。
多重选择
当要处理多个选项时,使用for循环会显得非常笨拙,可以使用switch语句:
int a = 10;
switch (a){
case 1:
System.out.println(1);
break;
case 2:
System.out.println(2);
break;
default:
System.out.println("其他");
}
实例中,我们可以看到switch语句的语句结构:
- switch语句将从选项值想匹配的case标签开始执行,直到遇到break语句或者switch语句结束。
- 如果没有匹配的case标签,会执行default语句
case标签可以是:
- 类型为char、byte、short或者int的常量表达式
- 枚举常量
- 字符串字面量
中断流程控制语句
Java中有两个终端流程控制语句:
- break
- continue
// break
for (int i = 0; i < 100; i++) {
if(i==10){
break;
}else{
System.out.println(i);
}
}
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
// continue
for (int i = 0; i < 100; i++) {
if (i == 10){
continue;
}else{
System.out.println(i);
}
}
示例中,展示了break和continue的不同。当循环执行break时,结束所有循环。当循环执行continue时,结束本次循环,执行下次循环。
Java还提供了一种带标签的break语句,用于跳出多重嵌套循环。
break_point: // 标签
while (true){
System.out.println(a++);
for (int i = 0; i < 100; i++) {
if (i==5){
break break_point; // break后紧跟标签。
}else {
System.out.println(i);
}
}
}
这段代码中,是一个while循环嵌套一个for循环。如果我们使用标签而是直接使用break。会只跳出内层的for循环,外层的while循环依旧执行。
如果我们想内层循环break时,外层循环也停止,需要使用标签。
-
标签是一个自定义的内容,写在最外层循环之前,并必须紧跟一个冒号。
-
break语句此时必须紧跟标签。
完成这些,在内层循环执行到break后,会同时跳出内存循环和外层循环。
大数
如果基本的整数和浮点数精度不能满足要求,可以使用math包中的两个类:
- BigInteger
- BigDecimal
BigInteger用于实现任意精度的整数运算;BigDecimal用于任意精度的浮点数运算。
官方推荐使用String参数类型的构造器来构造大数的对象,避免损失精度。
BigDecimal bd1 = BigDecimal.valueOf(1.23);
BigDecimal bd2 = new BigDecimal("2.23");
大数的相关计算方法详见API。
数组
数组是一种数据结构,它拥有以下几个特点:
- 数组储存的元素类型均相同
- 数组占用一段连续的内存空间。
- 数组元素是有序的
创建数组
java中数组有三种创建方式:
int[] arr1 = {1,2,3,4,5};
int[] arr2 = new int[]{1,2,3,4,5};
int[] arr3 = new int[5];
前两种创建方式会先创建数组,然后为数组种的元素赋值。第三种只是创建了数组,元素并未赋值,所以会使用元素的数据类型的默认值。
各种数据类型的默认值如下:
数据类型 | 默认值 |
---|---|
boolean | false |
object | null |
其他 | 0 |
数组创建时必须指定元素的类型和数组的长度,并且数组的长度一旦指定,就无法更改。
访问数组元素
数组中每个元素都有一个下标,数组的下标从0开始。
我们可以通过数组的下标访问数组元素。
int num = arr1[0]; // 访问数组arr1的第一个元素
数组操作
关于数组的常规操作,可使用java.util.Arrays工具类中的方法。
多维数组和不规则数组
略