1 方法的初始化

1.1 类的基本概念

(1)属性:描述对象的特征(C++中的数据成员)
(2)方法:描述对象的行为(C++中的成员函数)
(3)类的内容:①成员变量 ②成员方法 ③成员内部类(Java特性)

1.2 成员变量的默认值


PS:Java的成员变量可以在类中进行初始化(C++不行)

1.3 构造方法及其重载

class Person{private String name;private int age;//  有两个参数的构造方法public Person(String name, int age) {this.name = name;this.age = age;}//    有一个参数的构造方法public Person(String name) {this.name = name;this.age = 18; //  默认18岁}public void speak() {System.out.println("大家好,我叫" + name + ",今年" + age + "岁啦");}
}
public class Demo {public static void main(String[] args) {Person p1 = new Person("李知因", 23);Person p2 = new Person("李知恩");p1.speak();p2.speak();}
}

PS:
(1)与C++类似,Java中的每个类都至少有一个构造方法,如果没有显式定义,系统将创建方法体为空的默认构造方法
(2)构造方法一般用public来修饰(单例模式使用private的构造方法)
(3)构造方法名与类名相同无返回值,参数可有可无

2 this关键字

this用于在方法中访问对象的其他成员,可理解为当前对象的引用

2.1 解决成员变量与局部变量的同名冲突问题

class Person{int age;                    //成员变量public Person(int age){     //局部变量this.age = age;         //局部变量赋值给成员变量}
}

2.2 在构造方法中调用其他构造方法

class Person {public Person(){System.out.println("无参的构造方法被调用了……");}public Person(String name) {this();   //调用无参的构造方法System.out.println("有参的构造方法被调用了……");}
}
public class Demo {public static void main(String[] args) {Person p = new Person("itcast");    //实例化对象}
}
/*
无参的构造方法被调用了……
有参的构造方法被调用了……
*/

PS:
(1)构造方法是在实例化对象时由JVM自动调用的,在程序中不能像调用其他方法一样调用构造方法
(2)只能在构造方法中使用this调用其他构造方法,不能在成员方法中使用
(3)在构造方法中,使用this的方法调用语句必须放在第一行,且只能出现一次

3 static关键字

static用于修饰类的成员,如成员变量、成员方法、代码块

3.1 静态变量的定义与使用

class Student {static String schoolName;  // 定义静态变量schoolName
}
public class Demo {public static void main(String[] args) {Student stu1 = new Student();        Student stu2 = new Student();Student.schoolName = "传智播客";      // 为静态变量赋值
//        stu1.schoolName = "传智播客";       // 为静态变量赋值System.out.println("我的学校是" + stu1.schoolName);     // 打印第一个学生对象的学校System.out.println("我的学校是" + stu2.schoolName);     // 打印第二个学生对象的学校}
}
/*
我的学校是传智播客
我的学校是传智播客
*/

PS:
①静态变量是用static修饰的成员变量,从属于类,为所有对象共享
②static只能修饰成员变量,不能修饰局部变量

3.2 静态方法的定义与使用

class Person {public static void sayHello() { // 定义静态方法System.out.println("hello");}
}
public class Demo {public static void main(String[] args) {Person.sayHello();          // 调用静态方法}
}
/*
hello
*/

PS:
(1)静态成员属于类,(在没有创建对象时)可通过“类名.成员名”来访问
(2)创建对象后,也可以通过“对象名.成员名”来调用静态成员
(3)静态方法只能调用静态成员

3.3 静态代码块的定义与使用

定义:静态代码块是用static修饰的代码块(用{ }括起来)
特点:静态代码块在创建对象加载类时执行,且只执行一次
作用:通常用于初始化成员变量

class Person {static String country;// 下面是一个静态代码块static {            country = "china";System.out.println("Person类中的静态代码块执行了");}
}
public class Demo {// 静态代码块static {           System.out.println("测试类的静态代码块执行了");}public static void main(String[] args) {// 下面的代码创建了三个Person对象,但是静态代码只会执行一次Person p1 = new Person();Person p2 = new Person();Person p3 = new Person();}
}
/*
测试类的静态代码块执行了
Person类中的静态代码块执行了
*/

PS:
(1)静态代码块只能调用静态成员
(2)与静态变量和静态方法不同,执行静态代码块需要创建对象,因为静态代码块是在加载类时执行的

3.4 单例模式

单例模式是Java的一种设计模式,可以保证类在程序运行期间只有一个对象。

class Single {// 1、私有化构造方法private Single() {}                  // 2、类中创建一个私有静态对象private static Single INSTANCE = new Single();// 3、提供返回该对象的静态方法public static Single getInstance() { return INSTANCE;}
}
public class Demo {public static void main(String[] args) {Single s1 = Single.getInstance();Single s2 = Single.getInstance();System.out.println(s1.equals(s2));}
}
/*
true
*/

PS:两次调用getInstance()得到的是同一个对象,说明Single是一个单例的类

单例模式的另一种形式↓

class Single {// 1、私有化构造方法private Single() {}                  // 2、类中创建一个对象public static final Single INSTANCE = new Single();}
public class Demo {public static void main(String[] args) {Single s1 = Single.INSTANCE;Single s2 = Single.INSTANCE;System.out.println(s1.equals(s2));}
}
/*
true
*/

4 类的继承

4.1 继承与重写

4.1.1 类的继承

class A extends B
PS:
(1)Java继承时采用extends关键字(C++声明继承方式)
(2)Java中的类只支持单继承,不支持多继承(与C++不同)
(3)多个类可以继承同一个父类

4.1.2 重写父类方法

(1)只能重写方法体
(2)重写父类方法时,子类不能使用比父类中被重写的方法更严格的访问权限。

4.2 super关键字

super关键字用于访问父类的成员

4.2.1 调用父类的成员变量

super.父类的成员变量

4.2.2 调用父类的成员方法

super.父类的成员方法

4.2.3 调用父类的构造方法

super(有参或无参);

PS:
(1)super调用父类构造方法的语句必须放在子类构造方法的第一行,且只能出现一次
(2)super VS this:
1)this可调用本类的成员变量和成员方法,可在构造方法中调用另一构造方法(横向调用)
2)super可调用父类的成员变量和成员方法,可在子类构造方法中调用父类构造方法(纵向调用)

4.3 Object类

4.3.1 简介

Object类是所有类的父类,通常被称为超类、基类或根类。当定义一个类时,如果没有使用extends关键字为这个类显式地指定父类,那么该类会默认继承 Object 类。

4.3.2 Object类常用方法

4.4 final关键字

final关键字可用于修饰类、变量和方法,它有"不可更改"或者"最终"的含义
(1)final修饰的类不能被继承
(2)final 修饰的方法不能被子类重写
(3)final修饰的变量(成员变量和局部变量)是常量,只能赋值一次

5 抽象类与接口

5.1 抽象类

抽象类与抽象方法用abstract关键字进行修饰。

//定义抽象类Animal
abstract class Animal { // 定义抽象方法shout()public abstract void shout();
}
//定义Dog类继承抽象类Animal
class Dog extends Animal {// 实现抽象方法shout(),编写方法体public void shout() {System.out.println("汪汪……");}
}
//定义测试类
public class Demo {public static void main(String[] args) {Dog dog = new Dog(); // 创建Dog类的实例对象dog.shout();         // 调用dog对象的shout()方法}
}
/*
汪汪……
*/

PS:
(1)包含抽象方法的类是抽象类(C++包含纯虚函数的类是抽象类)
(2)抽象类不能被实例化,抽象方法没有方法体,不能被调用

5.2 接口

5.2.1 JDK8的接口

接口是一种特殊的抽象类。在JDK8中,除了抽象方法,接口中还可以有默认方法静态方法,且这两种方法都能有方法体

5.2.2 接口的定义与实现

//定义了Animal接口
interface Animal {int ID = 1;          // 定义全局常量void breathe();    // 定义抽象方法// 定义一个默认方法default void getType(String type){System.out.println("该动物属于:"+type);}// 定义一个静态方法public static int getID(){return Animal.ID;}
}
//Dog类实现了Animal接口
class Dog implements Animal {// 实现breathe()方法public void breathe() {System.out.println("狗在呼吸");}
}
//定义测试类
public class Demo {public static void main(String args[]) {System.out.println(Animal.getID()); // 调用静态方法Dog dog = new Dog();               // 创建Dog类的对象System.out.println(dog.ID);         // 获取接口全局常量dog.breathe();                       // 调用已实现的抽象方法dog.getType("犬科");               // 调用接口默认方法}
}
/*
1
1
狗在呼吸
该动物属于:犬科
*/

PS:
(1)接口中的方法默认为抽象方法用“public abstract”修饰
(2)接口中的变量默认为全局常量用“public static final”修饰
(3)接口无法被实例化,需要定义一个类,并实现(implements)接口的所有抽象方法(若该类为抽象类,则只需实现部分方法)
(4)一个接口可继承多个接口,用extends来声明继承关系
(5)一个类只能继承一个类(单继承),但可以实现多个接口,还可以在继承父类的同时实现接口,用implements来声明实现关系(此时extends需在implements之前)

6 多态性

6.1 多态

Java通过在方法中传入不同类型的对象实现多态,形参是父类类型(C++通过虚函数实现多态)

//定义接口Anmal
interface Animal {    void shout();     // 定义抽象shout()方法
}
//定义Cat类实现Animal接口
class Cat implements Animal {//实现shout()方法public void shout() {System.out.println("喵喵……");}
}
//定义Dog类实现Animal接口
class Dog implements Animal {// 实现shout()方法public void shout() {System.out.println("汪汪……");}
}
//定义测试类
public class Demo {public static void main(String[] args) {Animal an1 = new Cat(); // 创建Cat对象,使用Animal类型的变量an1引用Animal an2 = new Dog(); // 创建Dog对象,使用Animal类型的变量an2引用animalShout(an1);       // 调用animalShout()方法,将an1作为参数传入animalShout(an2);       // 调用animalShout()方法,将an2作为参数传入}
// 定义静态的animalShout()方法,接收一个Animal类型的参数public static void animalShout(Animal an) {an.shout();             // 调用实际参数的shout()方法}
}
/*
喵喵……
汪汪……
*/

6.2 对象的类型转换

将子类对象赋值给父类对象实质上是C++的赋值兼容问题,此时父类对象只能调用子类从父类继承的方法,而不能调用子类新增的方法

PS:用instanceof可以判断一个对象是否为某个类(或接口)的实例,将父类对象强转为子类类型,从而调用原本无法调用的子类方法

//定义接口Anmal
interface Animal {    void shout();     // 定义抽象shout()方法
}
//定义Cat类实现Animal接口
class Cat implements Animal {// 实现shout()方法public void shout() {System.out.println("喵喵……");}
}
//定义Dog类实现Animal接口
class Dog implements Animal {// 实现shout()方法public void shout() {System.out.println("汪汪……");}
}
//定义测试类
public class Demo {public static void main(String[] args) {Animal an1 = new Cat(); // 创建Cat对象,使用Animal类型的变量an1引用Animal an2 = new Dog(); // 创建Dog对象,使用Animal类型的变量an2引用animalShout(an1);       // 调用animalShout()方法,将an1作为参数传入animalShout(an2);       // 调用animalShout()方法,将an2作为参数传入}
// 定义静态的animalShout()方法,接收一个Animal类型的参数public static void animalShout(Animal animal) {if(animal instanceof Cat) {   // 判断animal是否为Cat类的实例对象Cat cat = (Cat)animal;    // 将animal强转为Cat类型cat.shout();}else if(animal instanceof Dog) {Dog dog = (Dog)animal;dog.shout();}}
}
/*
喵喵……
汪汪……
*/

7 内部类

在Java中,允许在类的内部定义类,即内部类,这个内部类所在的类称为外部类。

7.1 内部类的种类

7.1.1 静态内部类

//定义外部类Outer
class Outer {static int m = 0; // 定义外部类静态变量mstatic class Inner {void show() {// 静态内部类访问外部类静态成员System.out.println("外部类静态变量m="+m);}}
}
//定义测试类
public class Demo {public static void main(String[] args) {// 静态内部类可以直接通过外部类创建Outer.Inner inner = new Outer.Inner(); inner.show();}
}
/*
外部类静态变量m=0
*/

PS:
(1)在主方法中创建静态内部类对象:外部类名.内部类名 变量名 = new 外部类名.内部类名();
(2)在静态内部类中只能访问外部类的静态成员
(3)非静态内部类中不允许定义静态成员

7.1.2 成员内部类

外部类与内部类互相访问彼此的成员

//定义外部类Outer
class Outer {int m = 0; // 定义外部类的成员变量// 定义外部类成员方法void test1() {System.out.println("外部类成员方法");}// 定义成员内部类Innerclass Inner {int n = 1;// 1、定义内部类方法,访问外部类成员变量和方法void show1() {System.out.println("外部类成员变量m="+m);test1();}void show2(){System.out.println("内部类成员方法");}}// 2、定义外部类方法,访问内部类变量和方法void test2() {Inner inner = new Inner();System.out.println("内部类成员变量n="+inner.n);inner.show2();}
}
//定义测试类
public class Demo {public static void main(String[] args) {Outer outer = new Outer();             // 创建外部类对象Outer.Inner inner = outer.new Inner(); // 创建内部类对象inner.show1();   // 测试在成员内部类中访问外部类成员变量和方法outer.test2();  // 测试在外部类中访问内部类成员变量和方法}
}
/*
外部类成员变量m=0
外部类成员方法
内部类成员变量n=1
内部类成员方法
*/

7.1.3 方法内部类

外部类与内部类互相访问彼此的成员

//定义外部类Outer
class Outer {int m = 0;void test1(){System.out.println("外部类成员方法");}void test2() {// 1、定义方法内部类Inner,在方法内部类中访问外部类变量和方法class Inner {int n = 1;void show() {System.out.println("外部类变量m="+m);test1();}}// 2、在创建方法内部类的方法中,调用方法内部类变量和方法Inner inner = new Inner();System.out.println("方法内部类变量n="+inner.n);inner.show();}
}
//定义测试类
public class Demo {public static void main(String[] args) {Outer outer= new Outer();outer.test2();    // 通过外部类对象调用创建了方法内部类的方法}
}
/*
方法内部类变量n=1
外部类变量m=0
外部类成员方法
*/

7.1.4 匿名内部类(见7.2.4)

7.2 内部类的作用

7.2.1 无限制地访问外部类的成员变量和方法

//定义外部类Outer
class Outer {private int m = 0; // 定义外部类的成员变量// 定义外部类成员方法void test() {System.out.println("外部类成员方法");}// 定义成员内部类Innerclass Inner {//  定义内部类方法,访问外部类(私有)成员变量和方法void show() {System.out.println("外部类成员变量m="+m);test();}}
}
//定义测试类
public class Demo {public static void main(String[] args) {Outer.Inner inner = new Outer().new Inner();    // 创建内部类对象inner.show();     // 测试在成员内部类中访问外部类成员变量和方法}
}
/*
外部类成员变量m=0
外部类成员方法
*/

7.2.2 实现信息隐藏

外部类不能使用 private 和 protected 来修饰,而内部类可以使用 private 和 protected 来修饰。当使用 private 来修饰内部类的时候,内部类就对外隐藏了。

interface Animal{void shout();
}class LandAnimal{private class Cat implements Animal{public void shout() {System.out.println("喵星人:你不知道我是如何发出喵喵声的");}}//   得到实例化的接口对象public Animal getCat() {return new Cat();}
}
//定义测试类
public class Demo {public static void main(String[] args) {LandAnimal landAnimal = new LandAnimal();Animal animal = landAnimal.getCat();animal.shout();}
}
/*
喵星人:你不知道我是如何发出喵喵声的
*/

PS:在主函数中,我们只能知道LandAnimal类的getCat()方法可以返回一个Animal类型的接口实例,但不知道这个实例是如何实现的,也不知道实现这一接口的类的名字,所以对外实现了信息隐藏。

7.2.3 间接实现多重继承

class A{public String name() {return "A";}
}class B{public String type() {return "class";}
}class C{// 内部类1继承Aprivate class InnerOne extends A{public String name() {return super.name();}}//  内部类2继承Bprivate class InnerTwo extends B{public String type() {return super.type();}}public void speak() {// 创建内部类对象,让其访问自己的成员方法InnerOne innerOne = new InnerOne();InnerTwo innerTwo = new InnerTwo();System.out.println("my name is "+ innerOne.name() + ", my type is " + innerTwo.type());}
}
//定义测试类
public class Demo {public static void main(String[] args) {C c = new C();c.speak();}
}
/*
my name is A, my type is class
*/

类C中有两个内部类 InnerOne 和 InnerTwo ,分别继承了类A和类B。由于类C可以访问内部类 InnerOne 和 InnerTwo 的成员,那么相当于类C间接地继承了类A和类B,打破了Java只支持单继承的限制

7.2.4 匿名内部类可以简化接口的实现

interface Animal {void shout();
}public class Demo {public static void main(String[] args) {String name = "小花";// 定义匿名内部类作为参数传递给animalShout()方法animalShout(new Animal() {// 实现shout()方法public void shout() {// JDK 8开始,方法内部类、匿名内部类可以访问非final的局部变量System.out.println(name + "喵喵...");}});}// 定义静态方法animalShout(),接收接口类型参数public static void animalShout(Animal an) {an.shout(); // 调用传入对象an的shout()方法}
}
/*
小花喵喵...
*/

8 Lambda表达式

8.1 Lambda表达式入门

8.1.1 简介

Lambda表达式可以简化接口的实现,也可以简化对集合以及数组数据的遍历、过滤和提取等操作。

一个Lambda表达式由三个部分组成,分别为参数列表、"->"和表达式主体,可以形象地理解为将一堆数据扔给方法体,其语法格式如下∶
([数据类型 参数名,数据类型 参数名,…])->{表达式主体}
(1)参数列表:用于向表达式主体(接口的抽象方法)传递所需的参数。可以省略参数的数据类型,同时,如果只有一个参数,则可以省略括号()
(2)->∶用来指定参数数据指向
(3)表达式主体∶即抽象方法体,如果表达式主体只有一条语句,那么可以省略包含主体的大括号。另外,在Lambda表达式主体中允许有返回值,当只有一条 return语句时,也可以省略 return关键字。
PS:适于实现仅有一个抽象方法的接口,作为方法的参数进行传递

8.1.2 用Lambda表达式实现接口

//定义动物类接口
interface Animal {void shout();
}
public class Demo {public static void main(String[] args) {String name = "小花";// 1、匿名内部类作为参数传递给animalShout()方法(用匿名内部类实现接口)animalShout(new Animal() {public void shout() {System.out.println("匿名内部类输出:" + name + "喵喵...");}});// 2、使用Lambda表达式作为参数传递给animalShout()方法(用Lambda表达式实现接口)animalShout(() -> System.out.println("Lambda表达式输出:" + name + "喵喵..."));}// 创建一个animalShout()静态方法,接收接口类型的参数public static void animalShout(Animal an) {an.shout();}
}
/*
匿名内部类输出:小花喵喵...
Lambda表达式输出:小花喵喵...
*/

PS:至此,我们学到了接口的3种实现方式:普通方式、匿名内部类、Lambda表达式。对比发现,当接口中只有一个抽象方法时,用Lambda表达式比用匿名内部类更为简洁。

8.2 函数式接口

函数式接口是特殊的接口,有且仅有一个抽象方法。Lambda 表达式就是Java中函数式编程的体现。

//定义无参、无返回值的函数式接口
@FunctionalInterface   //标注函数式接口
interface Animal {void shout();
}
//定义有参、有返回值的函数式接口
interface Calculate {int sum(int a, int b);
}
public class Demo {public static void main(String[] args) {// 分别对两个函数式接口进行测试animalShout(() -> System.out.println("无参、无返回值的函数式接口调用"));showSum(10, 20, (x, y) -> x + y);}// 创建一个动物叫的方法,并传入接口对象Animal作为参数private static void animalShout(Animal animal) {animal.shout();}// 创建一个求和的方法,并传入两个int类型以及接口Calculate类型的参数private static void showSum(int x, int y, Calculate calculate) {System.out.println(x + "+" + y + "的和为:" + calculate.sum(x, y));}
}
/*
无参、无返回值的函数式接口调用
10+20的和为:30
*/

8.3 方法引用与构造器引用

Lambda表达式的主体只有一条语句时,程序不仅可以省略包含主体的大括号,还可以通过英文双冒号"::"的语法格式来引用方法和构造器,这两种形式可以进一步简化 Lambda表达式的书写,其本质都是对 Lambda表达式的主体部分已存在的方法进行直接引用,主要区别就是对普通方法与构造方法的引用而已。(说白了作用就是简化Lambda表达式的书写,写好了Lambda表达式后可以优化一下

题外话:引用方法有两种基本方式,通过类名对象名。引用构造器也有两种基本方式,通过 thissuper 关键字。讲真,这些基本方式已经够用了,还有没有必要掌握其他方式?或者像文化人说的,有没有必要知道茴香豆的“茴”有多少种写法?完全没必要嘛。嗯……但是,做开发是要看别人写的代码的,每个人的习惯可能有所不同,所以为了能看懂别人写的代码,还是有必要了解一下其他方法的。

  • Lambda表达式支持的引用类型

8.3.1 类名引用普通方法

//定义一个函数式接口
@FunctionalInterface
interface Printable{void print(StringUtils su, String str);
}
class StringUtils {public void printUpperCase(String str) {System.out.println(str.toUpperCase());}
}
//定义测试类
public class Demo {private static void printUpper(StringUtils su, String text, Printable pt) {pt.print(su, text); }public static void main(String[] args) {// 使用Lambda表达式printUpper(new StringUtils(), "Hello", (object, str) -> object.printUpperCase(str));// 使用类名引用普通方法printUpper(new StringUtils(), "Hello", StringUtils::printUpperCase);}
}
/*
HELLO
HELLO
*/

8.3.2 类名引用静态方法

//定义一个函数式接口
@FunctionalInterface
interface Calcable {int calc(int num);
}
//定义一个类,并在类中定义一个静态方法
class Math {// 定义一个求绝对值方法public static int abs(int num) {if (num < 0) {return -num;} else {return num;}}
}
//定义测试类
public class Demo {private static void printAbs(int num, Calcable calcable) {System.out.println(calcable.calc(num));}public static void main(String[] args) {// 1、使用Lambda表达式printAbs(-10, n -> Math.abs(n));// 2、使用类名引用静态方法printAbs(-10, Math::abs);}
}
/*
10
10
*/

总结:类的普通方法和静态方法都可以通过“类名::方法名”的方式进行调用。

8.3.3 对象名引用方法

对象名::方法名

//定义一个函数式接口
@FunctionalInterface
interface Printable{void print(String str);
}
class StringUtils {public void printUpperCase(String str) {System.out.println(str.toUpperCase());}
}
//定义测试类
public class Demo {private static void printUpper(String text, Printable pt) {pt.print(text); }public static void main(String[] args) {StringUtils stu = new StringUtils();// 使用Lambda表达式printUpper("Hello", str -> stu.printUpperCase(str));// 使用对象名调用方法printUpper("Hello", stu::printUpperCase);}
}
/*
HELLO
HELLO
*/

8.3.4 构造器引用

类名::new

//定义一个函数式接口
@FunctionalInterface
interface PersonBuilder {Person buildPerson(String name);
}
//定义一个Person类,并添加有参构造方法
class Person {private String name;public Person(String name) {this.name = name;}public String getName() {return name;}
}
//定义测试类
public class Demo {public static void printName(String name, PersonBuilder builder) {System.out.println(builder.buildPerson(name).getName());}public static void main(String[] args) {// 使用Lambda表达式方式printName("李知恩", name -> new Person(name));// 使用构造器引用的方式printName("李知恩", Person::new);}
}
/*
李知恩
李知恩
*/

9 异常

Java自带异常类,通过异常处理机制对程序运行时出现的各种问题进行处理。

9.1 异常概要

9.1.1 Throwable类

9.1.2 Throwable类常用方法

9.1.3 异常的类型

(1)编译时异常,这种异常必须要进行处理
(2)运行时异常,这种异常即使不编写异常处理代码,依然可以通过编译,但在运行时可能出现异常。

9.2 捕获并处理异常

try…catch和finally

public class Demo {// 下面的方法实现了两个整数相除public static int divide(int x, int y) {try {int result = x / y;      // 定义一个变量result记录两个数相除的结果return result;           // 将结果返回} catch (Exception e) {         // 对异常进行捕获处理System.out.println("捕获的异常信息为:" + e.getMessage());e.printStackTrace();} finally {System.out.println("执行finally代码块,无论程序是否异常,都会执行");}// 定义当程序发生异常直接返回-1return -1;}public static void main(String[] args) {int result = divide(4, 0);       // 调用divide()方法if(result == -1){           // 对调用方法返回结果进行判断System.out.println("程序发生异常!");}else{System.out.println(result);}}
}
/*
捕获的异常信息为:/ by zero
java.lang.ArithmeticException: / by zeroat demo/demo.Demo.divide(Demo.java:7)at demo/demo.Demo.main(Demo.java:19)
执行finally代码块,无论程序是否异常,都会执行
程序发生异常!
*/

PS:无论程序是发生异常还是用return语句结束,finally代码块都会执行(除非在此之前调用了System.exit),所以在实际开发中经常在finally中完成必须做的事,如释放系统资源、关闭线程池等

9.3 throws关键字

throws关键字用于声明方法可能抛出的异常,并将出现的异常从当前方法向上抛出,转交其调用者进行异常处理(其调用者也可以继续将该异常抛出)。

public class Demo {// 下面的方法实现了两个整数相除,并使用throws关键字声明抛出异常public static int divide(int x, int y) throws Exception {int result = x / y;      //定义一个变量result记录两个数相除的结果return result;           //将结果返回}public static void main(String[] args) {try {int result = divide(4, 0);  //调用divide()方法System.out.println(result); } catch (Exception e) {         //对捕获到的异常进行处理System.out.println("捕获的异常信息为:" + e.getMessage());}}
}

9.4 throw关键字

与 throws有所不同的是,throw用于方法体内,并且抛出的是一个异常类对象,而 throws关键字用在方法声明中,用来指明方法可能抛出的多个异常。

  • 在方法中抛出异常对象
public class Demo {// 定义printAge()输出年龄public static void printAge(int age) throws Exception {if(age <= 0){// 对业务逻辑进行判断,当输入年龄为负数时抛出异常throw new Exception("输入的年龄有误,必须是正整数!");}else {System.out.println("此人年龄为:"+age);}}public static void main(String[] args)  {// 下面的代码定义了一个try…catch语句用于捕获异常int age = -1;     try {printAge(age);} catch (Exception e) {  // 对捕获到的异常进行处理System.out.println("捕获的异常信息为:" + e.getMessage());}}
}
/*
捕获的异常信息为:输入的年龄有误,必须是正整数!
*/

9.5 自定义异常

Java允许自定义异常,但自定义的异常必须继承Exception类或其子类。在实际开发中,如果没有特殊的要求,自定义的异常类只需继承 Exception类,在构造方法中使用super()语句调用 Exception 的构造方法即可。

//下面的代码是自定义一个异常类继承自Exception
class DivideByMinusException extends Exception{public DivideByMinusException (){super();          // 调用Exception无参的构造方法}public DivideByMinusException (String message){super(message);  // 调用Exception有参的构造方法}
}public class Demo {// 下面的方法实现了两个整数相除,public static int divide(int x,int y) throws DivideByMinusException {if (x < 0) {// 使用throw关键字声明异常对象throw new DivideByMinusException("被除数是负数!");}int result = x / y; // 定义一个变量result记录两个数相除的结果return result;      // 将结果返回}public static void main(String[] args) {try {int result = divide(-2, 3);System.out.println(result);} catch (DivideByMinusException e) {System.out.println("捕获的异常信息为:" + e.getMessage());}}
}
/*
捕获的异常信息为:被除数是负数!
*/

PS:throw用于在方法体中抛出一个异常类对象。通过 throw关键字抛出异常后,调用者还需要使用throws关键字或try…catch对异常进行处理。如果 throw抛出的是Error、RuntimeException或它们的子类异常对象,则无须使用 throws关键字或 try…catch 对异常进行处理。

10 其他

10.1 垃圾回收

Java中引入了垃圾回收机制,JVM会在垃圾堆积到一定程度时自动回收垃圾对象所占的内存,因此不必过于担心垃圾对象的回收问题。

  • 通知JVM立即进行垃圾回收
class Person {// 下面定义的finalize方法会在垃圾回收前被调用public void finalize() {    //重写finalize方法System.out.println("对象将被作为垃圾回收...");}
}
public class Demo {public static void main(String[] args) {// 下面是创建了两个Person对象Person p1 = new Person ();Person p2 = new Person ();// 下面将变量置为null,让对象成为垃圾p1 = null;p2 = null;// 调用方法进行垃圾回收System.gc();for (int i = 0; i < 1000000000; i++) {// 为了延长程序运行的时间}}
}
/*
对象将被作为垃圾回收...
对象将被作为垃圾回收...
*/

PS:finalize()会在释放对象时自动调用,必须用public进行修饰,且返回值类型为void

10.2 Java帮助文档

Java文档注释格式:/**……*/,可在命令行中使用javadoc命令生成HTML格式的帮助文档

/**
* Title: Person类
* Description: 通过Person类来说明Java中的文档注释
* Company: Outcast
* @author Outcast
* @version 1.0
*/
public class Person {public String name;/*** 这是Person类的构造方法* @param name Person的名字*/public Person(String name){//        执行语句;}/*** 这是read()方法的说明* @param bookName 读的书的名字* @param time 读书所需的时间* @return 读的书的数量*/public int read(String bookName,int time){return time;}
}

用命令行生成帮助文档

javadoc -d . -version -author Person.java

PS:
①-d:指定输出文档存放的目录
② . :表示当前目录
③-version:指定输出文档需包含版本信息
④-author:指定输出文档需包含作者信息

在当前目录下打开HTML文件即可查看文档信息

10.3 包

10.3.1 定义并使用包

Java中的包用于存放类,通常功能相同的类存放在相同的包中

  • 包的声明
package demo;    //demo为包名

PS:包的声明必须位于源文件第一行

  • 编译声明了包的源文件
javac -d . Hello.java    //生成带包目录的.class文件并存放在当前目录下

PS:
(1)-d用于指定生成的类文件存放的位置
(2). 表示当前目录
(3)也可以把 .class文件放在其他目录下,如

javac -d E:\wordspace Hello.java    //生成带包目录的.class文件并存放在E:\wordspace文件夹中
  • 运行声明了包的源文件
java demo.Hello

10.3.2 导包

(1)导入类的语法:import 包名.类名
(2)当需要使用的类较多时,可用“import 包名.*”来导入该包下所有的类
(3)Java常用包

10.3.3 打包Java程序

jar命令可以将类文件打包成“.jar”文件(也称jar包),使用jar包时,只需在classpath环境变量中包含此jar文件的路径

  • 压缩jar文件
jar -cvf Hello.jar demo    //把demo目录下的全部内容生成一个Hello.jar文件

PS:
(1)-c用于创建归档的文件
(2)-v代表在标准输出中生成详细输出
(3)-f用于指定生成的文件名

  • 打开MANIFEST.MF文件,指定jar包的主类(先将jar包解压,再以记事本方式打开MANIFEST.MF文件)
Main-Class: demo.Hello    //指定jar包的主类为demo.Hello
  • 运行jar文件
java -jar Hello.jar

【黑马程序员】《Java基础入门》——02 面向对象相关推荐

  1. 黑马 程序员——Java基础---流程控制

    黑马程序员--Java基础---流程控制 ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------ 一.概述 Java提供了两种基本的流程控制结构:分支结构 ...

  2. 黑马 程序员——Java基础---IO(下)

    黑马程序员--Java基础---IO(下) ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------ 一.概述 Java除了基本的字节流.字符流之外,还提供 ...

  3. 黑马程序员-Java基础:面向对象(上)

    ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 一.面向对象概述 当需求单一,或者简单时,我们一步一步去操作没问题,并且效率也挺高.可随着需求的 ...

  4. 黑马程序员--Java基础加强篇

    开发工具使用 --------------------------------------------------------------------------------------------- ...

  5. 黑马程序员-Java基础:设计模式总结

    --Java培训.Android培训.iOS培训..Net培训.期待与您交流! -- Java基础部分设计模式 一.设计模式概述 设计模式(Design pattern)是一套被反复使用.多数人知晓的 ...

  6. 黑马程序员----------------java基础-----------------Map集合

     ------- <a href="http://www.itheima.com" target="blank">android培训</a ...

  7. 黑马程序员-Java基础知识预备之Java流程控制与数组

    -------- android培训.java培训.期待与您交流!---------- 本博文涉及的主要内容如下: if语句 switch语句 循环结构 循环结构的控制 数组类型 数组在内存中的运行机 ...

  8. 黑马程序员—java基础总结1

    ------- android培训.java培训.期待与您交流! ---------- 一:java概述: 1991 年Sun公司的James Gosling等人开始开发名称为 Oak 的语言,希望用 ...

  9. 黑马程序员 — JAVA基础 — 内部类、异常

    -----------android培训.java培训.java学习型技术博客.期待与您交流!------------ 一.内部类 1.概念: 把类定义在另一个类的内部,该类就被称为内部类. Eg:把 ...

  10. 黑马程序员-Java基础加强之枚举

    --------- android培训.java培训.期待与您交流!---------- 一.为什么要有枚举? 问题:要定义季节.星期向或性别的变量,该怎么定义?假设用1-4分别表示春.夏.秋.冬,但 ...

最新文章

  1. FTP服务(vsftpd)配置
  2. 为什么使用依赖注入?
  3. ASP.NET Web API 安全筛选器
  4. python的正则表达式 re
  5. react学习(48)--编辑回显用moment处理
  6. 信息学奥赛一本通(1163:阿克曼(Ackmann)函数)
  7. DataGridView控件的使用 1206 半草稿
  8. 思科交换机配置dhcp参数
  9. win10中配置Java完整教程
  10. sqlplus 乱码的资料
  11. python天天向上代码解析-python列表解析和生成器表达式
  12. 用互联网模式打造智慧城市的“城市云”
  13. kubernetes视频教程笔记 (15)-RC、RS和Deployment的关联
  14. druid mysql 时序_Druid时序数据库常见问题及处理方式
  15. Qt安装QtCharts | 超简便方法
  16. 词根词缀 按字母划分
  17. DGIOT 工业物联网开源平台简介
  18. win10 蓝牙耳机 连接后输出 没有耳机选择 的 解决办法
  19. 使用U盘安装win7系统遇到“缺少所需的 CD/DVD 驱动器设备驱动程序”解决办法
  20. ORACLE内核参数

热门文章

  1. python 堆叠柱状图 多列 复杂_[Python Study Notes]堆叠柱状图绘制
  2. 巴西龟饲养日志----冬眠苏醒
  3. B2B2C 商业模式
  4. 噪声分析基础(公式)知识
  5. 2017年度最值得读的AI论文 | CV篇 · 评选结果公布
  6. F623光猫超级管理员密码获取
  7. Github每日精选(第48期):SQLite下的知识库memos
  8. 论文阅读:FASTEMIT: LOW-LATENCY STREAMING ASR WITH SEQUENCE-LEVEL EMISSION REGULARIZATION
  9. 《Fundamentals Of Computer Graphics》虎书第三版翻译——第六章 矩阵变换
  10. RFID固定资产管理系统更好更快捷的掌握资产情况 资产盘查好帮手