---
title: Java语法基础
date: 2020-05-16 19:39:06
tags: 
- Java
categories:
- Java基础
---

## 注释、标识符，关键字

### 注释

<!--more-->

平时我们编写代码，在代码量比较少的时候，我们还可以看懂自己写的，但是当项目结构一旦复杂起来，我们就需要用到注释了。

注释并不会被执行，是给写代码的人看的。

<span style = color:red>写注释是一个很好的习惯</span>

<span style = color:red>写代码要注意规范</span>

Java的注释有三种：单行注释；多行注释；文档注释

```java
//单行注释

/*
 多行注释
 多行注释
*/

//JavaDoc:文档注释	/** 	*/
//javadoc命令是用来生成自己API文档的
/**
 * @author  作者名
 * @version 版本号
 * @since 指明需要最早使用的jdk版本
 * @param 参数名
 * @return 返回值情况
 * @throws 异常抛出情况
 */
```

JavaDoc ，可通过终端命令生成Api文档

```bash
javadoc -encoding UTF-8 -charset UTF-8 *.java
```

也可以通过Intellij IDEA生成，在工具栏中找到 <u>T</u>ools------>Generate Java<u>D</u>oc…

![](https://i.loli.net/2020/05/15/5FeQRjBkPAirSKs.png)

### 关键字

![Java关键字](https://i.loli.net/2020/05/11/EjmKrwpXdu632gI.png)

### 标识符

<span style = color:red>Java所有的组成部分都需要名字。类名、变量名以及方法名都被称为标识符。</span>

`标识符注意点：`

* 所有的标识符都应该以字母（A-z或者a-z），美元符（$）、或者下划线（_）开始
* 首字符之后可以是字母（A-Z或者a-z），美元符（$）、下划线（_）或数字的任何字符组合。
* <span style = color:red>不能使用关键字作为变量名或方法名。</span>
* 标识符是<span style = color:red>大小写敏感</span>的
* <span style = color:red>可以使用中文命名，但是一般不建议这样去使用，也不建议使用拼音，很Low，不规范</span>

```java
//合法标识符举例：age、$salary、value、_1_value
//非法标识符举例：123abc、-salary、#abc
//中文命名举例
public static void main（string[]args）{
	string 王者荣耀="最强王者";
    System.out.println(王者荣耀);
}
```



## 数据类型

Java是强类型语言，要求变量的使用要严格符合规定，所有变量都必须先定义后才能使用。

![](https://i.loli.net/2020/05/11/NucZLt9mwnkRMyA.png)

```java
// 八大基本数据类型
//整数
int num1 = 10;
byte num2 = 20;
short num3 = 30;
long num3 = 30L;	//long类型要在数字后加个 L
//小数：浮点数
float num5 = 50.1F;	//float类型要在数字后加个 F
double num6 = 3.1415926535;
//字符型
char name1 = 'A';	//引号内只能有一个字符
//布尔值:只有是(true)、非(false) 两个值
boolean flag1 = true;
boolean flag2 = false;
```

> 位（bit）：是计算机内部数据储存的最小单位，11001100是一个八位二进制数。
>
> 字节（byte）：是计算机中数据处理的基本单位，习惯上用大写B来表示，1B（byte，字节）=8bit（位）
>
> 字符：是指计算机中使用的字母、数字、字和符号
>
> 1bit表示1位，1Byte表示一个字节1B=8b。1024B=1KB，1024KB=1MB，1024MB=1GB…

### 数据类型拓展

#### 整数拓展

进制问题：

二进制 0b；十进制；八进制 0；十六进制 0x

```java
int i = 0b10;	//二进制	输出2
int i1 = 10;	//十进制	输出10
int i2 = 010;	//八进制	输出8
int i3 = 0x10;	//十六进制	输出16
```

#### 浮点数拓展

float和double类型，表现的长度是有限的，同时它也是离散的，它存在`舍入误差`的问题，他的结果是一个大约数，接近但不等于。

<span style = color:red>尽量不要使用浮点数进行比较，尤其是在做涉及钱的业务时。</span>

看下面的例子：

```java
float f = 0.1f;	//0.1
double d = 1.0/10;	//0.1
System.out.println(f==d);	//结果为false

float d1 = 2132154645646f;
float d2 = d1 + 1;
System.out.println(d1==d2);	//结果为true
```

我们可以看出，浮点数是存在误差的。

Java中，我们可以用`BigDecimal`这个数学工具类来执行上述的操作。

#### 字符拓展

所有字符本质还是数字

编码： Unicode码   u0000-uFFFF —>`UTF-8`，UTF-16，UTF-32

```java
//字符强制转换
char c1 = 'a';
char c2 = '中';
System.out.println(c1);	//输出 a
System.out.println((int)c1); //强制转换 输出 97
System.out.println(c2);	//输出 中
System.out.println((int)c2); //输出 20013
    
char c3 = '\u0061';		//十六进制
System.out.println(c3);	//输出 a
```

转义字符

| 转义字符 |                             作用                             |
| :------: | :----------------------------------------------------------: |
|    \n    |                             换行                             |
|    \t    |                          水平制表符                          |
|    \r    |                 回车，将当前位置移到本行开头                 |
|    \b    |                  退格，将当前位置移到前一列                  |
|    \f    |                 换页，将当前位置移到下页开头                 |
|   \\\    |                   代表一个反斜线字符''\\'                    |
|   \\'    |                  代表一个单引号（撇号）字符                  |
|   \\"    |                      代表一个双引号字符                      |
|    \0    |                         空字符(NULL)                         |
|   \ddd   |          1到3位八进制数所代表的任意字符 \000 ~ \377          |
|  \uxxxx  | Unicode转义字符，\u + 四个十六进制数字所代表的字符 \u0000 ~ \uFFFF |

#### 布尔值拓展

```java
 boolean flag = true;
//下面的方式是同样的效果，都表示当flag为真时，做什么
if (flag == true) {}
if (flag){} 
```

<span style = color:red>Less is More,代码要精简易读</span>

## 类型转换

由于Java是强类型语言，所以要进行有些运算的时候，需要用到类型转换。

```java
低--------------------------------------->高
byte,short,char->int->long->float->double
    //浮点数优先级一定大于整数
```

运算中，不同类型的数据先转换为同一类型，然后进行运算。

```java
 int i = 128;
//强制类型转换  (类型)变量名	高-->低
byte b =(byte)i;    //byte类型范围为-128-127，转换后内存溢出
//自动类型转换  	低-->高
double d = i;
System.out.println(i);		//输出 128
System.out.println(b);		//输出 -128
System.out.println(d);		//输出 128.0

System.out.println((int)23.7);  //输出23
System.out.println((int)-45.54f);  //输出 -45
```

<span style ="color:red"><b>注意:</b></span>

* 在类型转换时，要注意<span style="color:red">数据类型的取值范围，避免内存溢出</span>。
* 不能对布尔值进行转换
* 不能把对象类型转换为不相干的类型
* 转换时还可能存在精度问题，比如将浮点数转换为int类型，会舍去小数部分。

**操作比较大的数的时候，注意溢出问题**

```java
//JDK7以后，数字之间可以用下划线分割，下划线并不会被打印出来
int money = 10_0000_0000;
int year = 20;
int total = money * year;  //输出total的值为-1474836480。因为结果超出了int的范围，溢出
long total2 = money * year; 
//输出total2的值为-1474836480。因为运算顺序是先计算等式右边的，再把结果转换为long类型赋值给total2，但转换之前的结果已经出问题了。
long total3 = money*((long)year); 
//这次total3的结果是正确的 先把一个数转换为long，这样等式右边计算时就是以long类型在计算，就不会发生溢出了
```

## 变量、常量、作用域

### 变量

变量就是可以变化的量！

Java是一种强类型语言，每个变量都必须声明其类型。

Java变量是程序中最基本的存储单元，其要素包括变量名，变量类型和<span style ="color:red">作用域</span>。

```java
type varNam [= value][{,varName[= value],...}];
//数据类型 变量名 = 值； 可以使用逗号隔开来声明多个同类型变量(不建议)。  
```

<span style ="color:red">**注意:**</span>

* 每个变量都有类型，类型可以是基本类型，也可以是引用类型。

* 变量名必须是合法的标识符。

* 变量声明是一条完整的语句，因此每一个声明都必须以分号结束。

#### 类变量、实例变量、局部变量

```java
public class Variable{
    static int allClicks = 0;  //类变量
    String str = "hello world";  //实例变量 从属于对象
    public void method(){
        int i = 0; //局部变量，必须声明和初始化值，作用域仅限这个方法之内
    }
}
```

类变量：从属于类，作用域是在这个类内，随类一起出现，一起消失。

实例变量：从属于对象；如果不进行初始化,数值类型默认值为 0 | 0.0，char类型默认为一个空格，布尔类型默认值为false；除了基本类型，其余的默认都为 null。

局部变量，必须声明和初始化值，作用域仅限方法之内。

### 常量

常量(constant)：<span style="color:red">初识化(initialize)后不能再改变值！</span>不会变动的值。

所谓常量可以理解成一种特殊的变量，它的值被设定后，在程序运行过程中不允许被改变。

常量名一般使用大写字符表示。

```java
final 常量名 = 值;
final double PI = 3.14;
```

> 说明：修饰符，不存在先后顺序， `final static double PI = 3.14`和`static final double PI = 3.14`是一样的。

### 变量的命名规范

* 所有变量、方法、类名：<span style="color:red">**见名知意**</span>
* 类成员变量：首字母小写和驼峰原则：monthSalary
* 局部变量：首字母小写和驼峰原则
* 常量：大写字母和下划线：MAX_VALUE
* 类名：首字母大写和驼峰原则：Man，GoodMan
* 方法名：首字母小写和驼峰原则：run()，runRun()



## 运算符

Java语言支持如下运算符：

```java 
算术运算符: +,-,*,/,%,++,--
赋值运算符: =
关系运算符: >,<,>=,<=,==,!=,instanceof
逻辑运算符: &&,||,!
位运算符:   &,|,^,~,>>,<<,>>>
条件运算符: ? :
扩展赋值运算符：+=,-=,*=,/=
```

### 算数运算符

#### 基本运算符 

```java
+(加),-(减),*(乘),/(除),%(模，取余)
```

```java
低--------------------------------------->高
byte,short,char->int->long->float->double
```

不同类型相互运算时，结果的类型总是与要计算的数中优先级最高的那个数的类型保持一致，但最低为int，即当只有short、byte、char相互运算时，结果仍为int类型。

```java
public class Test {
    public static void main(String[] args) {
        double a = 123.123;
        float b = 123.123F;
        long c = 123123123123123L;
        int d = 123;
        short e = 10;
        byte f =8;
        char g = 'a';

        System.out.println(getType(a+b+c+d+e+f+g)); //double类型
        System.out.println(getType(b+c+d+e+f+g));   //float类型
        System.out.println(getType(c+d+e+f+g));     //long类型
        System.out.println(getType(d+e+f+g));       //int
        System.out.println(getType(e+f+g));         //int
        System.out.println(getType(f+g));           //int

    //获取变量类型的方法
    private static String getType(Object o){
        return o.getClass().toString();
    }

}
```

#### 自增自减运算符

```java
// ++  --   自增，自减   一元运算符
int a = 3;
int b = a++;//后置自增,执行这行代码时,先将a的值赋给b,a再自增
System.out.println(a);  // 4
int c = ++a;//前置自增,执行这行代码时,先将a自增,再将自增后的结果赋给c
System.out.println(a);  //5
System.out.println(b);  //3
System.out.println(c);  //5
```

### 关系运算符

关系运算符计算后返回的结果是`布尔值`，常与`if`判断语句结合使用。

### 逻辑运算符

```java
//	&&(与),||(或),!(非)
//逻辑与运算：两个变量都为真，结果才为true
//逻辑或运算：两个变量有一个为真，则结果才为true
//非：如果是真则变为假，如果是假则变为真
boolean a = true;
boolean b = false;
System.out.println(a&&b);	//false
System.out.println(a||b);	//true
System.out.println(!(a&&b));//true

//短路运算
int c = 5;
boolean d = (c < 4)&&(c++ < 4); //如果&&前面的为false，则后面的不会被运算
System.out.println(c);  //5，说明c++没有被运算
System.out.println(d);	//false
```

### 位运算

```
A和B都是二进制数
A = 0011 1100		
B = 0000 1101

A&B = 0000 1100		按位与：都为1时为1，其他情况为0
A|B = 0011 1101		按位或：都为0时为0，其他情况为1
A^B = 0011 0001		按位异或：相同为0，不同为1
~B = 1111 0010		按位取反
_________________________________________________

<<：左移，每移一位相当于乘以2
>>：右移，每移一位相当于除以2
如 2<<3 = 16
```

位运算由于是操作二进制数，所以效率极高。

### 扩展运算符

看下面例子

```java
a += b;	//就相当于 a=a+b
a -= b;	//就相当于 a=a-b
// 同样*=、/=也是这样的
```

### 条件运算符

```tex
条件运算符是三元运算符
x ? y : z
如果x为真，则结果为有，否则结果为z
```

### 运算符优先级

| 优先级 | 运算符                                             | 结合性   |
| ------ | -------------------------------------------------- | -------- |
| 1      | ()、[]、{}                                         | 从左向右 |
| 2      | !、+、-、~、++、--                                 | 从右向左 |
| 3      | *、/、%                                            | 从左向右 |
| 4      | +、-                                               | 从左向右 |
| 5      | <<、>>、>>>                                        | 从左向右 |
| 6      | <、<=、>、>=、instanceof                           | 从左向右 |
| 7      | ==、!=                                             | 从左向右 |
| 8      | &                                                  | 从左向右 |
| 9      | ^                                                  | 从左向右 |
| 10     | \|                                                 | 从左向右 |
| 11     | &&                                                 | 从左向右 |
| 12     | \|\|                                               | 从左向右 |
| 13     | ? :                                                | 从右向左 |
| 14     | =、+=、-=、*=、/=、&=、\|=、^=、~=、<<=、>>=、>>>= | 从右向左 |

### 拓展

1. 字符串连接符    +

	```java
	int a = 10;
	int b = 20;
	System.out.println("引号在前面"+a+b);// 输出 引号在前面1020
	System.out.println(a+b+"引号在后面");// 输出 30引号在后面
	```

可见，如果字符串在前面，则它后面连接的内容不会进行运算，如果字符串在后面，则它前面连接的内容会进行运算。

2. 很多运算，我们需要一些工具类来操作！如下代码用`Math`类进行幂运算。

	```java
	double power = Math.pow(2,3); //2的3次方，8.0
	```

## 包机制

为了更好地组织类，Java提供了包机制，用于区别类名的命名空间。

包语句的语法格式为：

```java
package pkg1[. pkg2[. pkg3...]];
```

<span style="color:red">一般利用公司域名倒置作为包名</span>

为了能够使用某一个包的成员，我们需要在Java 程序中明确导入该包。使用`import`语句可完成此功能

```java
import package1[.package2...].(classname|*);
```



