四、java基础语法
1. 注释
书写注释是一个非常好的习惯
注释并不会被执行,是给我们写代码的人看的
-
单行注释 //我是单行注释
-
多行注释 /*我是多行注释
我是多行注释*/
-
文档注释 //JavaDoc:文档注释 /** */
/** * @Description HelloWorld * @Author haohao_不秃头 */
2. 标识符和关键字
2.1 标识符
概念:就是用于给程序中的变量、类、方法命名的符号;
Java 所有的组成部分都需要名字。类名、变量名以及方法名都被称为标识符。
标识符规则:
- 标识符可以有字母、数字、下划线_、和美元符号$组成,并且数字不能打头
- 标识符不能使java关键字和保留字,但可以包含关键字和保留字
- 标识符是大小写敏感的
- 标识符不能包含空格
- 标识符只能包含美元符号$,不能包含@、#等其他特殊字符
- 分隔符:分号; 花括号{} 方括号[] 括号() 空格 圆点.;
可以使用中文命名,但是一般不建议这样使用,也不建议使用拼音,很Low
2.2 关键字
java中包含50个关键,所有关键字都是小写的
三个特殊的直接量(iteral);true false null 都不是关键字
- final修饰变量,则等同于常量
- final修饰方法中的参数,称为最终参数。
- final修饰类,则类不能被继承
- final修饰方法,则方法不能被重写。
abstract | assert | boolean | break | byte |
---|---|---|---|---|
case | catch | char | class | const |
continue | default | do | double | else |
enum | extends | final | finally | float |
for | goto | if | implements | import |
instanceof | int | interface | long | native |
new | package | private | protected | public |
return | strictfp | short | static | super |
switch | synchronized | this | throw | throws |
transient | try | void | volatile | while |
关键字 | 含义 |
---|---|
abstract | 表明类或者成员方法具有抽象属性 |
assert | 断言,用来进行程序调试 |
boolean | 基本数据类型之一,声明布尔类型的关键字 |
break | 提前跳出一个块 |
byte | 基本数据类型之一,字节类型 |
case | 用在switch语句之中,表示其中的一个分支 |
catch | 用在异常处理中,用来捕捉异常 |
char | 基本数据类型之一,字符类型 |
class | 声明一个类 |
const | 保留关键字,没有具体含义 |
continue | 回到一个块的开始处 |
default | 默认,例如,用在switch语句中,表明一个默认的分支。Java8 中也作用于声明接口函数的默认实现 |
do | 用在do-while循环结构中 |
double | 基本数据类型之一,双精度浮点数类型 |
else | 用在条件语句中,表明当条件不成立时的分支 |
enum | 枚举 |
extends | 表明一个类型是另一个类型的子类型。对于类,可以是另一个类或者抽象类;对于接口,可以是另一个接口 |
final | 用来说明最终属性,表明一个类不能派生出子类,或者成员方法不能被覆盖,或者成员域的值不能被改变,用来定义常量 |
finally | 用于处理异常情况,用来声明一个基本肯定会被执行到的语句块 |
float | 基本数据类型之一,单精度浮点数类型 |
for | 一种循环结构的引导词 |
goto | 保留关键字,没有具体含义 |
if | 条件语句的引导词 |
implements | 表明一个类实现了给定的接口 |
import | 表明要访问指定的类或包 |
instanceof | 用来测试一个对象是否是指定类型的实例对象 |
int | 基本数据类型之一,整数类型 |
interface | 接口 |
long | 基本数据类型之一,长整数类型 |
native | 用来声明一个方法是由与计算机相关的语言(如C/C++/FORTRAN语言)实现的 |
new | 用来创建新实例对象 |
package | 包 |
private | 一种访问控制方式:私用模式 |
protected | 一种访问控制方式:保护模式 |
public | 一种访问控制方式:共用模式 |
return | 从成员方法中返回数据 |
short | 基本数据类型之一,短整数类型 |
static | 表明具有静态属性 |
strictfp | 用来声明FP_strict(单精度或双精度浮点数)表达式遵循[IEEE 754](https://baike.baidu.com/item/IEEE 754)算术规范 |
super | 表明当前对象的父类型的引用或者父类型的构造方法 |
switch | 分支语句结构的引导词 |
synchronized | 表明一段代码需要同步执行 |
this | 指向当前实例对象的引用 |
throw | 抛出一个异常 |
throws | 声明在当前定义的成员方法中所有需要抛出的异常 |
transient | 声明不用序列化的成员域 |
try | 尝试一个可能抛出异常的程序块 |
void | 声明当前成员方法没有返回值 |
volatile | 表明两个或者多个变量必须同步地发生变化 |
while | 用在循环结构中 |
3. 数据类型
3.1 数据类型
- 强类型语言(Java、C/C++、Python)
- 强类型语言也称为强类型定义语言。是一种总是强制类型定义的语言,要求变量的使用要严格符合规定,所有变量必须先定义后才能使用
- 弱类型语言(VB、PHP、JavaScript)
- 数据类型可以被忽略的语言。它与强类型定义语言相反, 一个变量可以赋不同数据类型的值。
java的数据类型分为两大类
- 基本数据类型(primtive type)
- 引用数据类型(reference type)
String不是属性类型,是类
3.2 什么是字节
-
位(bit):是计算机 内部数据 储存的最小单元,11001100就是一个八位二进制数
-
字节(byte):是计算机中 数据处理 的基本单位,习惯用大写B来表示
- 1B(字节) = 8 bit(位)
-
字符:是指计算机中使用的字母、数字、字和符号
-
思考:电脑的32位和64位的区别是什么呢?
3.3 数据类型扩展及面试题
3.3.1 进制
- 二进制 0b
- 十进制
- 八进制 0
- 十六进制 0X
3.3.2浮点数的误差
举例
System.out.println(0.2 + 0.1); System.out.println(0.3 - 0.1); System.out.println(0.2 * 0.1); System.out.println(0.3 / 0.1);
输出:
0.30000000000000004 0.19999999999999998 0.020000000000000004 2.9999999999999996
浮点数误差的产生原因
- 由于计算机内部以二进制保存,所以十进制的有限位的小数,在计算机内部会是一个无限位的小数。
- 例如 十进制的0.9虽然只有一位小数,转成2进制是无限循环小数0.1110011001100110011…
- 计算机保存浮点数的精度有限,例如float可以保留十进制最多7位(二进制23位)有效数字,double 可以保留十进制15~16位(二进制52位)有效数字。那有效数字以后的就被忽略了。
- 例如上面的0.9的表示受精度所限,精度以后的就被忽略了,这样float时,它是0.89999998double时,它是0.90000000000000002
误差避免(使用 BigDecima)
BigDecimal简介
- Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算。双精度浮点型变量double可以处理16位有效数。在实际应用中,需要对更大或者更小的数进行运算和处理。float和double只能用来做科学计算或者是工程计算,在商业计算中要用java.math.BigDecimal。BigDecimal所创建的是对象,我们不能使用传统的+、-、*、/等算术运算符直接对其对象进行数学运算,而必须调用其相对应的方法。方法中的参数也必须是BigDecimal的对象。构造器是类的特殊方法,专门用来创建对象,特别是带有参数的对象。
构造器描述
- BigDecimal(int) 创建一个具有参数所指定整数值的对象。
BigDecimal(double) 创建一个具有参数所指定双精度值的对象。 //不推荐使用
BigDecimal(long) 创建一个具有参数所指定长整数值的对象。
BigDecimal(String) 创建一个具有参数所指定以字符串表示的数值的对象。//推荐使用
方法描述
- add(BigDecimal) BigDecimal对象中的值相加,然后返回这个对象。
subtract(BigDecimal) BigDecimal对象中的值相减,然后返回这个对象。
multiply(BigDecimal) BigDecimal对象中的值相乘,然后返回这个对象。
divide(BigDecimal) BigDecimal对象中的值相除,然后返回这个对象。
toString() 将BigDecimal对象的数值转换成字符串。
doubleValue() 将BigDecimal对象中的值以双精度数返回。
floatValue() 将BigDecimal对象中的值以单精度数返回。
longValue() 将BigDecimal对象中的值以长整数返回。
intValue() 将BigDecimal对象中的值以整数返回。
3.4 类型转换
3.4.1 值类型与引用类型
值类型:
在Java中,值类型表示的是这种数据类型的值代表数据本身。八种基本数据类型就是值类型,基本数据类型都是直接存储在内存中的内存栈上的,数据本身的值就是存储在栈空间里面。
引用类型:
引用类型是通过class来定义的类型,除了八种数据类型之外的所有类型都是引用类型。引用类型继承于Object类(也是引用类型)都是按照Java里面存储对象的内存模型来进行数据存储的,使用Java内存堆和内存栈来进行这种类型的数据存储,简单地讲,“引用”是存储在有序的内存栈上的,而对象本身的值是存储在内存堆上的。
传递
- 值传递:基本数据类型的赋值都属于值传递,值传递传递的是实实在在的变量值,是传递原参数的备份,值传递后,实参传递给形参的值,形参发生改变不影响实参。
- 引用传递:引用传递传递的是地址,形参改变会改变实参变量的值。
3.4.2 自动类型转换
1、基本数据类型
从低位类型到高位类型可以自动转换,从高位类型到低位类型需要强制类型转换,另外,目标类型需能与源类型兼容。
- 布尔型和其它基本数据类型之间不能相互转换;
- char可转换为int、long、float和double,其他类型不能转换为char;
- 其他六种类型从低到高的排序为:byte、short、int、long、float、double;
- 算术运算中,基本会先转换为高位数据类型,再参加运算,结果也是最高位的数据类型。
public class Test { public static void main(String[] args) { int price = 3; double finalPrice = price; System.out.println(finalPrice); System.out.println(price+finalPrice); /*输出结果: 3.0 6.0*/ } }
特殊情况:
- 如采用+=、*=等缩略形式的运算符,系统会自动强制将运算结果转换为目标变量的类型。
- 当运算符为自动递增运算符(++)或自动递减运算符(–)时,如果操作数为byte,short或char,类型不发生改变;
2、引用类型
- 基本类型与对应包装类可自动转换,这是自动装箱和拆箱的原理。
- 子类能直接转换为父类或接口类型: 子类就是父类。
Animal cat = new Cat();
- 父类转换为子类要强制类型转换;且在运行时若实际不是对应的对象,会抛出ClassCastException运行时异常。
3.4.3 强制类型转换
1、基本数据类型
- 存储范围大的类型到存储范围小
- 语法:( 数据类型 ) 数值
- 此时可能会丢失精度
public class Test { public static void main(String[] args) { double finalPrice = 3.25; int price = (int)finalPrice; System.out.println(price); //输出结果:3 //损失了部分数据 } }
2、引用类型
语法与上述相同,需要注意若转换后在运行时实际不是对应的对象,会抛出ClassCastException运行时异常。
Animal animal = new Cat(); Cat cat = (Cat)animal;
-
注意点:
-
不能对布尔值进行转换
-
不能把对象类型转换为不相干的类型
-
在把高容量转换为低容量时,强制转换
-
转换的时候可能存在内存溢出,或者精度问题
-
4. 变量、常量、作用域
4.1 变量
- 变量是什么:就是可以变化的量!
- Java是一种强类型语言,每个变量都必须声明其类型。
- Java变量是程序中最基本的存储单元,其要素包括变量名,变量和作业域
type varName [=value] [{,varName[=value]}]; //数据类型 变量名 = 值;可以使用逗号隔开来声明多个同类型变量 //不提倡同时声明多个变量,要分开写 int a, b, c; int a=1, b=2, c=3; //程序可读性
- 注意事项:
- 每个变量都有类型,类型可以是基本类型,也可以是引用类型。
- 变量名必须是合法的表示符。
- 变量声明是一条完成的语法,因此每一个声明都必须以分号结束。
4.2 变量作用域
- 类变量(静态变量):独立于方法之外的变量,用 static 修饰。
- 实例变量:独立于方法之外的变量,不过没有 static 修饰。
- 局部变量:类的方法中的变量。
public class Variable { static int allClicks = 0; //类变量 String str = "hell world"; //实例变量 public void method(){ int i = 0; //局部变量 } }
4.2.1 类变量(静态变量)
- 类变量也称为静态变量,在类中以 static 关键字声明,但必须在方法之外。
- 无论一个类创建了多少个对象,类只拥有类变量的一份拷贝。
- 静态变量除了被声明为常量外很少使用,静态变量是指声明为 public/private,final 和 static 类型的变量。静态变量初始化后不可改变。
- 静态变量储存在静态存储区。经常被声明为常量,很少单独使用 static 声明变量。
- 静态变量在第一次被访问时创建,在程序结束时销毁。
- 与实例变量具有相似的可见性。但为了对类的使用者可见,大多数静态变量声明为 public 类型。
- 默认值和实例变量相似。数值型变量默认值是 0,布尔型默认值是 false,引用类型默认值是 null。变量的值可以在声明的时候指定,也可以在构造方法中指定。此外,静态变量还可以在静态语句块中初始化。
- 静态变量可以通过:ClassName.VariableName的方式访问。
- 类变量被声明为 public static final 类型时,类变量名称一般建议使用大写字母。如果静态变量不是 public 和 final 类型,其命名方式与实例变量以及局部变量的命名方式一致。
实例
import java.io.*; public class Employee { //salary是静态的私有变量 private static double salary; // DEPARTMENT是一个常量 public static final String DEPARTMENT = "开发人员"; public static void main(String[] args){ salary = 10000; System.out.println(DEPARTMENT+"平均工资:"+salary); } }
以上实例编译运行结果如下:
开发人员平均工资:10000.0
4.2.2 实例变量
- 实例变量声明在一个类中,但在方法、构造方法和语句块之外;
- 当一个对象被实例化之后,每个实例变量的值就跟着确定;
- 实例变量在对象创建的时候创建,在对象被销毁的时候销毁;
- 实例变量的值应该至少被一个方法、构造方法或者语句块引用,使得外部能够通过这些方式获取实例变量信息;
- 实例变量可以声明在使用前或者使用后;
- 访问修饰符可以修饰实例变量;
- 实例变量对于类中的方法、构造方法或者语句块是可见的。一般情况下应该把实例变量设为私有。通过使用访问修饰符可以使实例变量对子类可见;
- 实例变量具有默认值。数值型变量的默认值是0,布尔型变量的默认值是false,引用类型变量的默认值是null。变量的值可以在声明时指定,也可以在构造方法中指定;
- 实例变量可以直接通过变量名访问。但在静态方法以及其他类中,就应该使用完全限定名:ObejectReference.VariableName。
实例
import java.io.*; public class Employee{ // 这个实例变量对子类可见 public String name; // 私有变量,仅在该类可见 private double salary; //在构造器中对name赋值 public Employee (String empName){ name = empName; } //设定salary的值 public void setSalary(double empSal){ salary = empSal; } // 打印信息 public void printEmp(){ System.out.println("名字 : " + name ); System.out.println("薪水 : " + salary); } public static void main(String[] args){ Employee empOne = new Employee("haohao"); empOne.setSalary(1000.0); empOne.printEmp(); } }
以上实例编译运行结果如下:
$ javac Employee.java $ java Employee 名字 : haohao 薪水 : 1000.0
4.2.3 Java 局部变量
- 局部变量声明在方法、构造方法或者语句块中;
- 局部变量在方法、构造方法、或者语句块被执行的时候创建,当它们执行完成后,变量将会被销毁;
- 访问修饰符不能用于局部变量;
- 局部变量只在声明它的方法、构造方法或者语句块中可见;
- 局部变量是在栈上分配的。
- 局部变量没有默认值,所以局部变量被声明后,必须经过初始化,才可以使用。
实例 1
在以下实例中age是一个局部变量。定义在pupAge()方法中,它的作用域就限制在这个方法中。
package com.runoob.test; public class Test{ public void pupAge(){ int age = 0; age = age + 7; System.out.println("小狗的年龄是: " + age); } public static void main(String[] args){ Test test = new Test(); test.pupAge(); } }
以上实例编译运行结果如下:
小狗的年龄是: 7
实例 2
在下面的例子中 age 变量没有初始化,所以在编译时会出错:
package com.runoob.test; public class Test{ public void pupAge(){ int age; age = age + 7; System.out.println("小狗的年龄是 : " + age); } public static void main(String[] args){ Test test = new Test(); test.pupAge(); } }
以上实例编译运行结果如下:
Test.java:4:variable number might not have been initialized age = age + 7; ^ 1 error
4.3 常量
- 常量(Constant):初始化(initialize)后不能再改变值!不会变动的值。
- 所谓常量可以理解成一种特殊的变量,它的值被设定后,在程序过程中不允许被改变。
final 常量名 = 值; final double PI = 3.14;
- 常量名一般使用大写字母。
4.4 变量的命名规范
- 所有变量、方法、类名:见名知意
- 类成员变量:首字母小写和驼峰原则:mothSalary 除第一个单词以外,后面单词首字母大写
- 局部变量:首字母小写和驼峰原则
- 常量:大写字母和下划线:MAX_VALUE
- 类名:大写字母和驼峰原则:Man,GoodMan
- 方法名:首字母小写和驼峰原则:run(),runRun()
5. 基本运算符
- 算数运算符:+,-,*,/,%,++,–
- 赋值运算符:=
- 关系运算符:>,<,>=,<=,==,!=,instanceof
- 逻辑运算符:&&,||,!
- 位运算符:&,|,^,~,>>,<<,>>>
- 条件运算符: ?:
- 扩展赋值运算符:+=,-=,*=,/=
6. 包机制
- 为了更好地组织类,javat提供了包机制,用于区分类名的命名空间
- 包语法的语法格式为:
package pkg1[. pkg2[. pkg3...]]
-
一般利用公司域名倒置作为包名 com.baidu.www
-
为了能够使用某一个包的成员,我们需要在 java 程序中明确的导入该包,使用“import”语句即可完成此功能
import package1[.package2...].(classname |*)
7. JavaDoc生成文档
-
javadoc命令是用来生成自己API文档的
-
参数信息
- @author 作者名
- @version 版本号
- @since 指明需要最早使用的jdk版本
- @param 参数名
- @return 返回值情况
- @throws 异常抛出情况