[关闭]
@songying 2018-12-13T13:12:21.000000Z 字数 7374 阅读 1398

java 语法基础

Java


运算符

几乎所有运算符都只能操作“主类型”(Primitives)。唯一的例外是“=”、“==”和“!=”,它们能操作所有对象,除此以外,String类支持“+”和“+=”。

操作符 描述 例子
+ 加法 - 相加运算符两侧的值 A + B 等于 30
- 减法 - 左操作数减去右操作数 A – B 等于 -10
* 乘法 - 相乘操作符两侧的值 A * B等于200
/ 除法 - 左操作数除以右操作数 B / A等于2
取模 - 左操作数除以右操作数的余数 B%A等于0
++ 自增: 操作数的值增加1 B++ 或 ++B 等于 21(区别详见下文)
-- 自减: 操作数的值减少1 B-- 或 --B 等于 19(区别详见下文)

对象与类

类中的变量类型

  • 局部变量

    • 在方法、构造方法或者语句块中定义的变量被称为局部变量。
    • 变量声明和初始化都是在方法中,方法结束后,变量就会自动销毁。
    • 局部变量是在栈上分配的。
    • 局部变量没有默认值,所以局部变量被声明后,必须经过初始化,才可以使用。
    • 访问修饰符不能用于局部变量;
  • 成员变量:成员变量是定义在类中,方法体之外的变量。这种变量在创建对象的时候实例化。成员变量可以被类中方法、构造方法和特定类的语句块访问。

  • 类变量:类变量也声明在类中,方法体之外,但必须声明为static类型。

构造方法

创建对象三步走

  • 声明:声明一个对象,包括对象名称和对象类型。
  • 实例化:使用关键字new来创建一个对象。
  • 初始化:使用new创建对象时,会调用构造方法初始化对象。

源文件声明规则

  1. 一个源文件中只能有一个public类
  2. 一个源文件可以有多个非public类
  3. 源文件的名称应该和public类的类名保持一致。
  4. 如果一个类定义在某个包中,那么package语句应该在源文件的首行。
  5. 如果源文件包含import语句,那么应该放在package语句和类定义之间。如果没有package语句,那么import语句应该在源文件中最前面。
  6. import语句和package语句对源文件中定义的所有类都有效。在同一源文件中,不能给不同的类不同的包声明。

修饰符

修饰符分为两类: 访问修饰符,非访问修饰符。

访问控制修饰符

  • default : 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。

  • private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)和接口。

  • public : 对所有类可见。使用对象:类、接口、变量、方法

  • protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)和接口

    • 子类与基类在同一包中:被声明为 protected 的变量、方法和构造器能被同一个包中的任何其他类访问;
    • 子类与基类不在同一包中:那么在子类中,子类实例可以访问其从基类继承而来的 protected 方法,而不能访问基类实例的protected方法。
    • 方法和成员变量能够声明为 protected,但是接口的成员变量和成员方法不能声明为 protected。
修饰符 当前类 同一包内 子孙类 其他包 其他包子孙类
public Y Y Y Y Y
protected Y Y Y N Y/N(说明
default Y Y N N N
private Y N N N N

- 父类中声明为 public 的方法在子类中也必须为 public。
- 父类中声明为 protected 的方法在子类中要么声明为 protected,要么声明为 public,不能声明为 private。
- 父类中声明为 private 的方法,不能够被继承。

非访问修饰符

1. static

  • 静态变量:

    static 关键字用来声明独立于对象的静态变量,无论一个类实例化多少对象,它的静态变量只有一份拷贝。 静态变量也被称为类变量。局部变量不能被声明为 static 变量。

  • 静态方法:

    static 关键字用来声明独立于对象的静态方法。静态方法不能使用类的非静态变量。静态方法从参数列表得到数据,然后计算这些数据。

2. final

  • final变量:

    • final 变量能被显式地初始化并且只能初始化一次。
    • 被声明为 final 的对象的引用不能指向不同的对象。但是 final 对象里的数据可以被改变。也就是说 final 对象的引用不能改变,但是里面的值可以改变。
    • final 修饰符通常和 static 修饰符一起使用来创建类常量。
  • final方法:

    • 类中的 final 方法可以被子类继承,但是不能被子类修改。
  • final类:

    • final 类不能被继承

3. abstract

  • 抽象类:

    • 抽象类不能用来实例化对象,声明抽象类的唯一目的是为了将来对该类进行扩充。
    • 一个类不能同时被 abstract 和 final 修饰。
    • 如果一个类包含抽象方法,那么该类一定要声明为抽象类,否则将出现编译错误。
    • 抽象类可以包含抽象方法和非抽象方法。
  • 抽象方法:

    • 抽象方法不能被声明成 final 和 static。
    • 任何继承抽象类的子类必须实现父类的所有抽象方法,除非该子类也是抽象类。
    • 如果一个类包含若干个抽象方法,那么该类必须声明为抽象类。抽象类可以不包含抽象方法。

4. synchronized

  • synchronized 关键字声明的方法同一时间只能被一个线程访问。synchronized 修饰符可以应用于四个访问修饰符。

5. transient ??

6. volatile

olatile 修饰的成员变量在每次被线程访问时,都强制从共享内存中重新读取该成员变量的值。而且,当成员变量发生变化时,会强制线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。

一个 volatile 对象引用可能是 null。

循环结构

1. while循环

  1. while( 布尔表达式 ) {
  2. //循环内容
  3. }

2. do ... while循环

  1. do {
  2. //代码语句
  3. }while(布尔表达式);

3. for循环

  1. for(初始化; 布尔表达式; 更新) {
  2. //代码语句
  3. }

4. 增强for循环

  1. for(声明语句 : 表达式)
  2. {
  3. //代码句子
  4. }
  • 声明语句:声明新的局部变量,该变量的类型必须和数组元素的类型匹配。其作用域限定在循环语句块,其值与此时数组元素的值相等。
  • 表达式:表达式是要访问的数组名,或者是返回值为数组的方法。

5. break

break 跳出最里层的循环,并且继续执行该循环下面的语句。

6. continue

  • continue 适用于任何循环控制结构中。作用是让程序立刻跳转到下一次循环的迭代。
  • 在 for 循环中,continue 语句使程序立即跳转到更新语句。
  • 在 while 或者 do…while 循环中,程序立即跳转到布尔表达式的判断语句。

分支结构

1. if语句

  1. if(布尔表达式)
  2. {
  3. //如果布尔表达式为true将执行的语句
  4. }
  1. if(布尔表达式){
  2. //如果布尔表达式的值为true
  3. }else{
  4. //如果布尔表达式的值为false
  5. }
  1. if(布尔表达式 1){
  2. //如果布尔表达式 1的值为true执行代码
  3. }else if(布尔表达式 2){
  4. //如果布尔表达式 2的值为true执行代码
  5. }else if(布尔表达式 3){
  6. //如果布尔表达式 3的值为true执行代码
  7. }else {
  8. //如果以上布尔表达式都不为true执行代码
  9. }

2. switch

  1. switch(expression){
  2. case value :
  3. //语句
  4. break; //可选
  5. default : //可选
  6. //语句
  7. }
  • switch 语句中的变量类型可以是: byte、short、int 或者 char。
  • case 语句中的值的数据类型必须与变量的数据类型相同,而且只能是常量或者字面常量。

数组

1. 声明数组

  1. dataType[] arrayRefVar;

2. 声明数组

  1. arrayRefVar = new dataType[arraySize];
  2. dataType[] arrayRefVar = {value0, value1, ..., valuek};

索引值从 0 到 arrayRefVar.length-1。

3. 多维数组

  1. type arrayName = new type[arraylenght1][arraylenght2];
  2. //从最高维开始,分别为每一维分配空间
  3. String s[][] = new String[2][];
  4. s[0] = new String[2];
  5. s[1] = new String[3];
  6. s[0][0] = new String("Good");

4. array类

java.util.Arrays 类能方便地操作数组,它提供的所有方法都是静态的。

序号 方法和说明
1 public static int binarySearch(Object[] a, Object key)用二分查找算法在给定数组中搜索给定值的对象(Byte,Int,double等)。数组在调用前必须排序好的。如果查找值包含在数组中,则返回搜索键的索引;否则返回 (-(插入点) - 1)。
2 public static boolean equals(long[] a, long[] a2)如果两个指定的 long 型数组彼此相等,则返回 true。如果两个数组包含相同数量的元素,并且两个数组中的所有相应元素对都是相等的,则认为这两个数组是相等的。换句话说,如果两个数组以相同顺序包含相同的元素,则两个数组是相等的。同样的方法适用于所有的其他基本数据类型(Byte,short,Int等)。
3 public static void fill(int[] a, int val)将指定的 int 值分配给指定 int 型数组指定范围中的每个元素。同样的方法适用于所有的其他基本数据类型(Byte,short,Int等)。
4 public static void sort(Object[] a)对指定对象数组根据其元素的自然顺序进行升序排列。同样的方法适用于所有的其他基本数据类型(Byte,short,Int等)。

方法

  1. 修饰符 返回值类型 方法名(参数类型 参数名){
  2. ...
  3. 方法体
  4. ...
  5. return 返回值;
  6. }

1. 构造方法

  • 造方法用来在对象创建时初始化该对象
  • 构造方法和它所在类的名字相同,但构造方法没有返回值。
  • Java自动提供了一个默认构造方法,它把所有成员初始化为0。一旦你定义了自己的构造方法,默认构造方法就会失效。

2. 可变参数

  1. typeName... parameterName
  2. public static void printMax( double... numbers){
  3. }
  • 一个方法中只能指定一个可变参数,它必须是方法的最后一个参数

3. finalize()方法

该方法在对象被垃圾收集器析构(回收)之前调用,用来清除回收对象。

Java 的内存回收可以由 JVM 来自动完成。如果你手动使用,则可以使用该方法。

  1. protected void finalize()
  2. {
  3. // 在这里终结代码
  4. }

异常

三种类型的异常:

  • 检查性异常:最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。
  • 运行时异常: 运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。
  • 错误: 错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到的。

捕获异常

  1. try{
  2. // 程序代码
  3. }catch(异常类型1 异常的变量名1){
  4. // 程序代码
  5. }catch(异常类型2 异常的变量名2){
  6. // 程序代码
  7. }finally{
  8. // 程序代码
  9. }

throw

继承

  1. class 子类 extends 父类 {
  2. }

继承的特性

  • 子类拥有父类非private的属性,方法。
  • Java的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如A类继承B类,B类继承C类,所以按照关系就是C类是B类的父类,B类是A类的父类,这是java继承区别于C++继承的一个特性。

implements

与extends不同的是,implements用来继承接口,且可以同时继承多个接口。

  1. public class C implements A,B {
  2. }

super, this

  • super关键字:我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。
  • this关键字:指向自己的引用。

final

  • final 关键字声明类可以把类定义为不能继承的,即最终类;

    1. final class 类名 {}
  • 用于修饰方法,该方法不能被子类重写:

    1. 修饰符(public/private/default/protected) final 返回值类型 方法名(){}

构造器

  • 子类不能继承父类的构造器(构造方法或者构造函数),但是父类的构造器带有参数的,则必须在子类的构造器中显式地通过super关键字调用父类的构造器并配以适当的参数列表。
  • 如果父类有无参构造器,则在子类的构造器中用super调用父类构造器不是必须的,如果没有使用super关键字,系统会自动调用父类的无参构造器。

重写(Override)

  • 写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!

    重写方法不能抛出新的检查异常或者比被重写方法申明更加宽泛的异常。例如: 父类的一个方法申明了一个检查异常 IOException,但是在重写这个方法的时候不能抛出 Exception 异常,因为 Exception 是 IOException 的父类,只能抛出 IOException 的子类异常。

  • 当需要在子类中调用父类的被重写方法时,要使用super关键字。

    1. class Dog extends Animal{
    2. public void move(){
    3. super.move(); // 应用super类的方法
    4. ///
    5. }
    6. }

重写规则

  • 参数列表必须完全与被重写方法的相同;
  • 返回类型必须完全与被重写方法的返回类型相同;
  • 访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为public,那么在子类中重写该方法就不能声明为protected。
  • 父类的成员方法只能被它的子类重写。
  • 声明为final的方法不能被重写。
  • 声明为static的方法不能被重写,但是能够被再次声明。
  • 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为private和final的方法。
  • 子类和父类不在同一个包中,那么子类只能够重写父类的声明为public和protected的非final方法。
  • 重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。
  • 构造方法不能被重写。

重载(Overload)

  • 重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。
  • 每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。
  • 最常用的地方就是构造器的重载。

重载规则

  • 被重载的方法必须改变参数列表(参数个数或类型或顺序不一样);
  • 被重载的方法可以改变返回类型;
  • 被重载的方法可以改变访问修饰符;
  • 被重载的方法可以声明新的或更广的检查异常;
  • 方法能够在同一个类中或者在一个子类中被重载。
  • 无法以返回值类型作为重载函数的区分标准。
区别点 重载方法 重写方法
参数列表 必须修改 一定不能修改
返回类型 可以修改 一定不能修改
异常 可以修改 可以减少或删除,一定不能抛出新的或者更广的异常
访问 可以修改 一定不能做更严格的限制(可以降低限制)

多态

抽象类

  1. public abstract class Employee{
  2. }

抽象方法

  1. public abstract class Employee{
  2. public abstract double computePay();
  3. }
  • 如果一个类包含抽象方法,那么该类必须是抽象类。
  • 任何子类必须重写父类的抽象方法,或者声明自身为抽象类。

接口

  1. [可见度] interface 接口名称 [extends 其他的类名] {
  2. // 声明变量
  3. // 抽象方法
  4. }
  • 接口是隐式抽象的,当声明一个接口的时候,不必使用abstract关键字。
  • 接口中每一个方法也是隐式抽象的,声明时同样不需要abstract关键字。
  • 接口中的方法都是公有的。

接口实现

  1. ...implements 接口名称[, 其他接口名称, 其他接口名称..., ...] ...
  • 当类实现接口的时候,类要实现接口中所有的方法。否则,类必须声明为抽象的类
  • Implements关键字放在class声明后面。

  • 类在实现接口的方法时,不能抛出强制性异常,只能在接口中,或者继承接口的抽象类中抛出该强制性异常。

  • 类在重写方法时要保持一致的方法名,并且应该保持相同或者相兼容的返回值类型。
  • 如果实现接口的类是抽象类,那么就没必要实现该接口的方法。

  • 一个类可以同时实现多个接口。

  • 一个类只能继承一个类,但是能实现多个接口。
  • 一个接口能继承另一个接口,这和类之间的继承比较相似。
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注