java基础语法


四、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修饰方法,则方法不能被重写。
abstractassertbooleanbreakbyte
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
浮点数误差的产生原因
  1. 由于计算机内部以二进制保存,所以十进制的有限位的小数,在计算机内部会是一个无限位的小数。
    • 例如 十进制的0.9虽然只有一位小数,转成2进制是无限循环小数0.1110011001100110011…
  2. 计算机保存浮点数的精度有限,例如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;
  • 注意点:

    1. 不能对布尔值进行转换

    2. 不能把对象类型转换为不相干的类型

    3. 在把高容量转换为低容量时,强制转换

    4. 转换的时候可能存在内存溢出,或者精度问题

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 异常抛出情况