Java学习

java入门学习当你们还在打完一局王者的时候,我就已经开始入门java了哈哈哈哈哈哈

这是好久之前总结的了,先试着发一发吧。

1.类变量

类变量也称为静态变量

静态变量随着类的创建而创建,所有的对象共享静态方法区,可通过对象调用也可直接通过类调用

特点:

  1. static变量是同一个类所有对象共享
  2. static类变量,在类加载的时候就生成了,因此可以不用创建对象再来使用
public class StaticMethod {public static void main(String[] args) {Stu tom = new Stu("tom");Stu.payFee(100);//通过类名来调用静态类变量Stu jack = new Stu("jack");Stu.payFee(200);//通过对象来调用Stu.showFee();}}
class Stu{private String name;//普通成员private static double fee = 0;//静态变量public Stu(String name) {this.name = name;}//说明public static void payFee(double fee){Stu.fee += fee;}public static void showFee(){System.out.println("总学费为:"+Stu.fee);}
}

类变量注意点

class D{private static int n1 = 100;public void say(){//可以使用this,super//普通成员方法既可以访问非静态成员,也可以访问静态成员System.out.println(this.n1);}public static void hi(){//类方法(静态方法)不可使用this,super和对象相关的关键字//静态方法只能访问静态成员System.out.println(n1);hi();}}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nLTMhaSt-1665747352537)(E:\学习笔记\图片\未命名文件 (2)].png)

2.代码块

  • 对构造器进行完善,多个构造器有重复的语句可以写在代码块,提高代码的重用性

  • 在构造器使用时会优先调用代码块中的内容

public class CodeBlock01 {public static void main(String[] args) {Movie movie = new Movie("你好,李焕英",100,"贾玲");}}
class Movie{private String name;private double price;private String director;//code block{System.out.println("Movie scree is opening...");System.out.println("advertisement is beginning....");System.out.println("Movie is starting...");}//构造器//In this way what kinds of constructor we call,we must first call the code block messagepublic Movie(String name) {this.name = name;}public Movie(String name, double price) {this.name = name;this.price = price;}public Movie(String name, double price, String director) {this.name = name;this.price = price;this.director = director;}}

1.静态代码块

对类进行初始化,而且它随着类的加载而执行,并且只会执行一次,如果是普通代码块,每创建一个对象,就执行一次

类什么时候被加载!!!

  1. 创建对象实例的时候
  2. 创建子类对象实例,父类也会加载,而且父类先被加载,子类后被加载
  3. 使用类的静态成员的时候(静态属性,静态方法)

普通代码块,在创建对象实例时,会被隐式的调用,被创建一次就会调用一次

如果只是使用类的静态成员时,普通代码块不会执行

public class CodeBlockDetail01 {public static void main(String[] args) {//类被加载的情况实例//创建对象实例的时候//AA aa1 = new AA();//        2.创建子类对象实例,父类也会加载//AA aa2 = new AA();
//        3.使用类的静态成员的时候(静态属性,静态方法)System.out.println(Cat.n1);}}
class BB{static {System.out.println("BB 的静态代码1被执行。。。");}
}
class AA extends BB{//静态代码块static {System.out.println("AA 的静态代码1被执行。。。");}
}
class Cat{public static int n1 = 999;static {System.out.println("Cat 的静态代码1被执行。。。");}
}

创建一个类时,在一个类的调用顺序:

1.调用静态代码块和静态属性初始化

静态代码块和静态属性初始化调用的优先级一样,如果有多个静态代码块和多个静态变量初始化,则按他们定义的顺序调用

public class CodeBlockDetail02 {public static void main(String[] args) {A a = new A();//会先输出getN1被调用 然后输出A 静态代码块01}
}
class A{//静态属性初始化private static int n1 =getN1();static {System.out.println("A 静态代码块01");}public static int getN1(){System.out.println("getN1被调用");return 100;}
}
  • 静态属性和静态代码块的优先级一样因为 属性在静态代码块前就被调用,所以先调用getN1,后调用静态代码块

    2.调用普通代码块和普通属性的初始化

普通代码块和普通属性初始化调用的优先级一样,如果有多个普通代码块和多个普通属性初始化按定义顺序调用

public class CodeBlockDetail02 {public static void main(String[] args) {A a = new A();}
}
class A{private int n2 = getN2();//静态属性初始化private static int n1 =getN1();{System.out.println("普通代码块");}static {System.out.println("A 静态代码块01");}public static int getN1(){System.out.println("getN1被调用");return 100;}public int getN2(){System.out.println("getN2被调用");return 200;}
//结果为:
getN1被调用
A 静态代码块01
getN2被调用
普通代码块

3.调用构造方法

public class CodeBlockDetail02 {public static void main(String[] args) {A a = new A(3);}
}
class A{private int n2 = getN2();//静态属性初始化private static int n1 =getN1();{System.out.println("普通代码块");}static {System.out.println("A 静态代码块01");}public static int getN1(){System.out.println("getN1被调用");return 100;}public int getN2(){System.out.println("getN2被调用");return 200;}public A(int n2) {System.out.println("A()构造器被调用");this.n2 = n2;}
}//结果:
getN1被调用
A 静态代码块01
getN2被调用
普通代码块
A()构造器被调用

2.普通代码块

调用顺序: 父类代码块->父类构造器->子类代码块->子类构造器

public class CodeBlockDetail03 {public static void main(String[] args) {new BBB();}
}
class AAA {{System.out.println("这是AAA的代码块");}public AAA(){System.out.println("AAA构造器被调用");}
}
class BBB extends AAA{{System.out.println("这是BBB的代码块");}public BBB(){System.out.println("BBB构造器被调用");}}结果:
这是AAA的代码块
AAA构造器被调用
这是BBB的代码块
BBB构造器被调用

3.静态代码块和普通代码块

执行顺序:父类静态->子类静态->父类普通(代码块和属性)->父类构造方法->子类普通(代码块和属性)->子类构造方法

3.单例设计模式

单例(单个实例)

使用单例模式能够保证整个应用中有且只有一个实例。解决问题的关键就是保证在应用中只有一个对象就行了,

其实只需要三步就可以保证对象的唯一性

(1)不允许其他程序用new对象。

因为new就是开辟新的空间,在这里更改数据只是更改的所创建的对象的数据,如果可以new的话,每一次new都产生一个对象,这样肯定保证不了对象的唯一性。

(2)在该类中创建对象
因为不允许其他程序new对象,所以这里的对象需要在本类中new出来

(3)对外提供一个可以让其他程序获取该对象的方法

因为对象是在本类中创建的,所以需要提供一个方法让其它的类获取这个对象。

那么这三步怎么用代码实现呢?将上述三步转换成代码描述是这样的

(1)私有化该类的构造函数(防止用户直接new)

(2)通过new在本类中创建一个本类对象

(3)定义一个公有的方法,将在该类中所创建的对象返回。getinstance

(4)代码实现

1.饿汉式单例模式

public class SingleTon01 {public static void main(String[] args) {GirlFriend instance = GirlFriend.getInstance();System.out.println(instance);GirlFriend instance1 = GirlFriend.getInstance();System.out.println(instance1);System.out.println(instance == instance1);//判断对象是否是同一个}
}
class GirlFriend {private String name;//2.在类的内部直接创建对象(该对象是static的)//饿汉模式可能造成创建了对象但是没有使用private static GirlFriend gf = new GirlFriend("小红");//1.私有化该类的构造函数private GirlFriend(String name){System.out.println("构造器被调用");this.name = name;}//3.提供一个公共的static方法,返回gf对象public static GirlFriend getInstance(){return gf;}@Overridepublic String toString() {return "GirlFriend{" +"name='" + name + '\'' +'}';}
}结果:
构造器被调用
GirlFriend{name='小红'}
GirlFriend{name='小红'}
true
//构造器在类加载时不被调用在创建对象时被调用

2.懒汉式单例模式

public class SingleTon02 {public static void main(String[] args) {//        new Cat();
//        System.out.println(Cat.n1);Cat instance = Cat.getInstance();System.out.println(instance);//再次调用Cat instance2 = Cat.getInstance();System.out.println(instance2);//判断对象是否是同一个System.out.println(instance == instance2);}
}
//懒汉式,只有当用户使用getinstance时,才返回cat对象,后面再次调用时,返回上次的对象,从而保证了单例//希望在程序运行的过程中,只能创建一个Cat对象
class Cat{private String name;public static int n1 = 999;//2.在类的内部定义对象(该对象是static的)private static Cat cat = null;//步骤//1.私有化该类的构造函数private Cat(String name){System.out.println("构造器调用");this.name = name;}@Overridepublic String toString() {return "Cat{" +"name='" + name + '\'' +'}';}//3.提供一个公共的static方法,返回gf对象//在此处有线程安全问题(同时有多个线程访问单例模式会被破坏)public static Cat getInstance(){if(cat == null){//如果没有创建cat对象cat = new Cat("大黄");}return cat;}
}构造器调用
Cat{name='大黄'}
Cat{name='大黄'}
true
//构造器在类加载时不被调用在创建对象时被调用

饿汉式和懒汉式的区别

1.二者最主要的区别是创建对象的时机不同:饿汉式是在类加载就创建了对象实例,懒汉式是在使用时创建

2.饿汉式不存在线程安全问题,懒汉式存在线程安全问题

3.饿汉式存在资源浪费问题

4.final关键字

用于修饰类、成员变量和成员方法,final修饰的类,不能被继承,其中所有的方法都不能被重写(不能被重写,但是可以被重载)Final修饰的方法不能被重写,但是子类可以用父类中final修饰的方法;

重写:
1.发生在父类与子类之间
2.方法名,参数列表,返回类型(除过子类中方法的返回类型是父类中返回类型的子类)必须相同
3.访问修饰符的限制一定要大于被重写方法的访问修饰符(public>protected>default>private)
4.重写方法一定不能抛出新的检查异常或者比被重写方法申明更加宽泛的检查型异常

重载:

1.重载Overload是一个类中多态性的一种表现
2.重载要求同名方法的参数列表不同(参数类型,参数个数甚至是参数顺序)
3.重载的时候,返回值类型可以相同也可以不相同。无法以返回型别作为重载函数的区分标准

深入理解一下被final修饰的类、方法、变量

1.final修饰的类

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uTYUdoz5-1665747352540)(E:\学习笔记\图片\22-4-22.jpg)]

final修饰的类不能够被继承

2.final修饰的变量

public final class Final01 {public static void main(String[] args) {String a = "xiaomeng2";final String b = "xiaomeng";String d = "xiaomeng";String c = b + 2;String e = d + 2;System.out.println((a == c));System.out.println((a == e));}//truefalse

b 是 final 修饰的,变量 b 的值在编译时候就已经确定了它的确定值,换句话说就是提前知道了变量 b 的内容到底是个啥,相当于一个编译期常量;

b 是一个常量,所以在使用 b 的时候直接相当于使用 b 的原始值(xiaomeng)来进行计算,所以 c 生成的也是一个常量,a 是常量,c 也是常量,都是 xiaomeng2 而 Java 中常量池中只生成唯一的一个 xiaomeng2 字符串,所以 a 和 c 是相等的!

a和c指向常量池中的xiaomeng2,

e的话由于使用的是 d 的引用计算,变量d的访问却需要在运行时通过链接来进行,所以这种计算会在堆上生成 xiaomeng2 ,e指向堆中的xiaomeng2

final修饰引用变量和基本变量有什么不同

基本变量:基本变量在被final修饰后就不可以改变

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-01xHWmtM-1665747352541)(E:\学习笔记\图片\Snipaste_2022-04-22_19-02-32.jpg)]

引用变量:基本变量在被final修饰后就不可以改变,但引用对象的内容可以改变

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZWKyQBBW-1665747352541)(E:\学习笔记\图片\Snipaste_2022-04-22_19-09-24.jpg)]

使用final修饰了的类不能再指向别处

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sGxhvVhO-1665747352542)(E:\学习笔记\图片\Snipaste_2022-04-22_19-05-07.jpg)]

final关键字的好处:

  1. final方法比非final快一些
  2. final关键字提高了性能。JVM和Java应用都会缓存final变量。
  3. final变量可以安全的在多线程环境下进行共享,而不需要额外的同步开销。
  4. 使用final关键字,JVM会对方法、变量及类进行优化。

3.final使用细节

  1. final修饰的属性又叫常量,一般用XX_XX(大写字母)来命名

  2. final修饰的属性在定义时必须赋初值,并且以后不能再更改赋值可以在以下位置进行

    1. 在定义时
    2. 在构造器中
    3. 在代码块中
    class AA{public final double TAX_RATE = 0.08;//在定义时public final double TAX_RATE2;//在构造器中public final double TAX_RATE3;//在代码块中public AA(){TAX_RATE2 = 1.1;}{TAX_RATE3 = 3.3;}}
    

    3.如果final修饰的属性是静态的,则初始化的位置只能是:(1)定义时(2)在静态代码块 (3)不能在构造器中赋值

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FlSj9eBd-1665747352543)(E:\学习笔记\图片\Snipaste_2022-04-23_20-15-27.jpg)]

    • 构造器在创建对象的时候才会被调用,而静态变量的初始化在类加载时就要给出值

    4.final类不能继承但是可以实例化对象

    public final class Final01 {public static void main(String[] args) {new CC();//实例化}}final class CC{}
    

    5.如果不是final类,但是含有final方法,则该方法虽然不能重写,但是可以被继承

     public static void main(String[] args) {new CC();EE ee = new EE();ee.cal();//cal()方法被继承}}class DD{public final void cal(String[] args) {System.out.println("cal()方法");}
    }
    class EE extends DD{}
    

    (了解即可)

    6.一般来说,如果一个类已经是final类了,就没必要将方法修饰成final方法

    7.final不能修饰构造器

    8.final和static往往搭配使用,效率更高,底层编译器做了优化(不会导致类加载)

    9.包装类(Integer,Double,Float,Boolean等都是final),string也是final类

5.抽象类

引论:为什么要有抽象类

class Animal{private String name;public Animal(String name) {this.name = name;}//这里eat方法 实现了但是没有意义//即:父类方法不确定性//===》 考虑将其写为抽象(abstract)方法//==》 一般来说抽象类会被继承,由其子类来实现抽象方法public void eat(){System.out.println("这是一个动物,但是不知道吃什么");}
}

所有的普通方法上面都会有一个“{}”,这个表示方法体,有方法体的方法一定可以被对象直接使用。而抽象方法,是指没有方法体的方法,同时抽象方法还必须使用关键字abstract做修饰

public class AbstractDemo01 {}
abstract class A{//定义一个抽象类public void fun(){//普通方法System.out.println("存在具体的方法");}public abstract void print();//抽象方法,没有方法体,有abstract关键字
}

1.抽象类细节

  1. 抽象类不能被实例化

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qVUtVRuH-1665747352543)(E:\学习笔记\图片\Snipaste_2022-04-23_21-02-12.jpg)]

2.抽象类不一定要包含abstract方法。

3.一旦类包含了抽象方法则类必须是抽象类

4.abstract只能修饰类和方法,不能修饰属性和其他的

5.抽象类可以有任意成员[抽象类的本质还是类]

6.抽象方法不能有主体(方法体),不能实现

7.如果一个类继承了抽象类,则他必须实现抽象类的所有方法,除非他本身也是抽象类

public class AbstractDetail01 {public static void main(String[] args) {new B().hi();}
}
abstract class A{public abstract void hi();
}
class B extends A{@Overridepublic void hi() {System.out.println("hi");}

8.抽象方法不能使用private、final和static来修饰,因为这些关键字都不允许重写

2.抽象类的最佳实践-模板设计模式

提高代码的复用性

abstract public class Tamplate {//抽象类-模板设计模式public abstract void job();public void calculateTime(){//调用了job方法//得到开始时间long start = System.currentTimeMillis();job();//得到结束时间long end = System.currentTimeMillis();System.out.println("AA执行时间"+(end - start));}
}public class AA  extends Tamplate{@Overridepublic void job(){long num = 0;for (int i = 0; i < 800000; i++) {num +=i;}}
}public class BB extends Tamplate{@Overridepublic void job(){long num = 0;for (int i = 0; i < 800000; i++) {num *= i;}}
}public class Test {public static void main(String[] args) {AA aa = new AA();aa.calculateTime();BB bb = new BB();bb.calculateTime();}
}

6.接口

usb插槽就是现实中的接口

1.入门

定义接口

public interface Usbinterface {//接口//规定接口的相关方法public void start();public void stop();
}

实现接口

//Phone类 实现 Usbinterface
//1.即phone类需要实现 usbinterface接口 规定/声明方法
public class Phone implements Usbinterface {@Overridepublic void start() {System.out.println("手机开始工作");}@Overridepublic void stop(){System.out.println("手机停止工作");}
}
public class Camera implements Usbinterface{@Overridepublic void start() {System.out.println("相机开始工作");}@Overridepublic void stop() {System.out.println("相机停止工作");}
}

调用接口

public class Computer {//编写一个方法public void work(Usbinterface usbinterface){//规定接口相关方法,定义了规范//通过接口来调用方法usbinterface.start();usbinterface.stop();}
}
public class Interface01 {public static void main(String[] args) {//创建手机,相机对象Phone phone = new Phone();Camera camera =new Camera();//创建计算机Computer computer = new Computer();computer.work(phone);//把手机接入到计算机System.out.println("============");computer.work(camera);//把相机接入到计算机}
}结果:
手机开始工作
手机停止工作
============
相机开始工作
相机停止工作

由上面的例子可以得出接口就是一些没有实现的的方法,封装到一起,到某个类要使用的时候,再根据具体情况把这些方法写出来

  • 接口是更加抽象的抽象类,抽象类的方法可以有方法体,接口里所有的方法都没有方法体
  • 接口体现了程序设计的多态和高内聚低耦合的设计思想

jdk8.0后接口类可以有静态方法,默认方法,也就是说接口中可以有方法体的具体实现

public interface AInterface {//写属性public int n1 = 10;//写方法//在接口中,抽象方法可以省略abstract关键字public void hi();//在jdk8后,可以有默认实现方法,需要使用default关键字修饰default public void ok(){System.out.println("ok.......");}//在jdk8后,可以有静态方法public static void cry(){System.out.println("cry......");}
}

2.什么时候使用接口

项目经理开发一个软件,为了控制和管理软件,项目经理可以定义一些接口,然后由程序员具体实现

可以使命名更加规范

接口

public interface DBInterface {//项目经理public void connect();//连接方法public void close();//关闭方法
}
//A程序员连接Mysql
public class MysqlDB implements DBInterface{@Overridepublic void connect() {System.out.println("连接mysql");}@Overridepublic void close() {System.out.println("关闭mysql");}
}
//B程序员连接Oracle
public class OracleDB implements DBInterface{@Overridepublic void connect() {System.out.println("连接Oracle");}@Overridepublic void close() {System.out.println("关闭Oracle");}
}
public class Interface03 {public static void main(String[] args) {MysqlDB mysqlDB = new MysqlDB();t(mysqlDB);}public static void t(DBInterface db){db.connect();db.close();}
//结果
连接mysql
关闭mysql

3.接口的使用细节

  1. 接口不能被实例化

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x420XgQM-1665747352544)(E:\学习笔记\图片\Snipaste_2022-04-24_00-17-56.jpg)]

2.接口中的方法是public方法,接口中抽象方法,可以不用abstract修饰

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fao8ZEqa-1665747352544)(E:\学习笔记\图片\Snipaste_2022-04-24_00-35-29.jpg)]

3.一个普通类实现接口,就必须将该接口的所有方法都实现,可以使用快捷键alt+enter来实现

4.抽象类实现接口可以不用实现接口方法

5.一个类同时可以实现多个接口

interface IB {void hi();
}
interface IC{void say();
}
//一个类可以实现多个接口
class Pig implements IB,IC{@Overridepublic void hi() {}@Overridepublic void say() {}
}

6.接口中的属性,只能是final的,而且是public static final修饰符,比如int a = 1;实际上是public static final int a = 1;(必须初始化)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0Rg5vXqK-1665747352545)(E:\学习笔记\图片\Snipaste_2022-04-24_00-53-46.jpg)]

7.接口中属性的访问:接口名.属性名

8.接口不能继承其他的类,但是可以继承多个别的接口

interface IB {int n1 =10;void hi();
}
interface IC extends{void say();
}
//接口不能继承其他的类,但是可以继承多个别的接口
interface ID extends IB,IC{}

9.接口的修饰符 只能是public和默认,这一点和类修饰符一样

4.实现接口和继承类的区别

  • 继承只能继承父类的方法(单继承)
public class ExtendsVsInterface {public static void main(String[] args) {LittleMonkey littleMonkey= new LittleMonkey("悟空");littleMonkey.climbing();}
}
//猴子
class Monkey{private String name;public Monkey(String name) {this.name = name;}public void climbing(){System.out.println(name+"会爬树");}
}class LittleMonkey extends Monkey{public LittleMonkey(String name) {super(name);}
}
  • 接口可以实现多种实现方法
//接口
interface Fishable{void swimming();
}
interface Birdable{void flying();
}
//实现接口
class LittleMonkey extends Monkey implements Fishable,Birdable{public LittleMonkey(String name) {super(name);}@Overridepublic void swimming() {System.out.println(getName()+"通过学习学会了游泳");}@Overridepublic void flying() {System.out.println(getName()+"通过学习学会了飞翔");}
}
//调用public static void main(String[] args) {LittleMonkey littleMonkey= new LittleMonkey("悟空");littleMonkey.climbing();littleMonkey.swimming();littleMonkey.flying();}
  • 接口和继承解决的问题不同

继承的价值主要在于:解决代码的复用性和可维护性

接口的价值主要在于:设计好各种规范,让其他类去实现这些方法,即更加的灵活

  • 接口在一定程度上实现代码的解耦[即:接口规范性+动态绑定]

5.接口的多态性

多态参数

public class InterfacePolyParameter {public static void main(String[] args) {//接口的多态体现//接口类型变量 if01可以指向实现了if接口类的对象实例IF if01 = new Monster();if01 = new Car();//继承实现多态//父类类型的变量 a 可以指向继承AAA的子类的对象实例AAA aaa = new BBB();aaa = new CCC();}
}interface IF{}class Monster implements IF{}
class Car implements IF{}
class AAA{}
class BBB extends AAA{}
class CCC extends AAA{}

多态数组

   public static void main(String[] args) {//多态数组 ->接口类型数组Usb[] usb = new Usb[2];usb[0] = new Phone_();//存放phone_类型usb[1] = new Camera_();//存放camera_类型for (int i = 0;i<usb.length;i++){usb[i].work();//进行类型的向下转型if (usb[i] instanceof Phone_){((Phone_) usb[i]).call();//强制转换}}}
}interface Usb{public void work();
}
class Phone_ implements Usb{public void call(){System.out.println("手机可以打电话");}@Overridepublic void work() {System.out.println("手机工作中");}
}
class Camera_ implements Usb{@Overridepublic void work() {System.out.println("相机工作中");}
}

多态传递

public class InterfacePolyPass {public static void main(String[] args) {IG ig = new Teacher();//如果IG继承了IH接口,而Teacher类实现了IG接口//Teacher也得实现IH接口IH ih = new Teacher();}
}interface IH{void hi();
}
interface IG extends IH{}
class Teacher implements IG{@Overridepublic void hi() {}
}

小练习

public class InterfaceExperience {public static void main(String[] args) {}
}
interface A {int x = 0;
} //想到 等价 public static final int x = 0;
class B {int x = 1;
} //普通属性
class C extends B implements A {public void pX() {//System.out.println(x); //错误,原因不明确 x//可以明确的指定 x
//访问接口的 x 就使用 A.x
//访问父类的 x 就使用 super.xSystem.out.println(A.x + " " + super.x);}public static void main(String[] args) {new C().pX();}
}

7.内部类

一个类的内部又嵌套了另一个类结构,被嵌套的类称为内部类

内部类的分类:

1.定义在外部类局部位置上(比如方法内):

  • 局部内部类(有类名)
  • 匿名内部类(没有类名)!!!!!!!!!!!!

2.定义在外部类的成员位置上:

  • 成员内部类(没用static修饰)
  • 静态内部类(使用static修饰)

1.局部内部类

1.局部内部类是定义在外部局部类的局部位置,通常在方法

2.可以直接访问外部类的所有成员,包含私有的

3.不能添加访问修饰符(因为它的地位就是一个局部变量。局部变量是不能使用修饰符的)但是可以使用final 修饰

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u49IZytS-1665747352545)(E:\学习笔记\图片\Snipaste_2022-04-24_21-25-39.jpg)]

4.作用域:仅仅在定义它的方法或代码块中

5.局部内部类-----访问----->外部类的成员[访问方式:直接访问]

6.外部类----->访问------>局部内部类的成员[访问方式:创建对象再访问(注意:必须在作用域内)]

public class LocalInnerClass {public static void main(String[] args) {Outer02 outer02 = new Outer02();outer02.m1();}
}class Outer02 {//外部类private int n1 = 100;private void m2() {System.out.println("Outer02 m2()");}//私有方法public void m1() {//方法//1.局部内部类是定义在外部局部类的局部位置,通常在方法//3.不能添加访问修饰符(因为它的地位就是一个局部变量。局部变量是不能使用修饰符的)但是可以使用final 修饰//4.作用域:仅仅在定义它的方法或代码块中final class Inner02 {//局部内部类(本质仍然是一个类)//2.可以直接访问外部类的所有成员,包含私有的public void f1() {//5.局部内部类可以直接访问外部类的成员System.out.println("n1=" + n1);m2();}}//6.外部类在方法中,可以创建局部内部类---访问------>局部内部类的成员Inner02 inner02 = new Inner02();inner02.f1();}{//代码块class Inner03{}}
}

7.外部其他类—>不能访问—>局部内部类(因为 局部内部类地位是一个局部变量)

8.如果外部类和局部内部类的成员重名时,如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问

public static void main(String[] args) {Outer02 outer02 = new Outer02();outer02.m1();System.out.println("outer02的hashcode="+ outer02);
}public void f1() {//5.局部内部类可以直接访问外部类的成员比如下面的n1和m2()System.out.println("n1=" + n1+"外部类n1= "+Outer02.this.n1);System.out.println("Outer02.this 的 hashcode=" + Outer02.this);m2();
}

2.匿名内部类

1.基于接口的匿名内部类

public class AnnonymousClass {public static void main(String[] args) {//基于接口的匿名内部类//1.需求:实现一个IA接口,并创建对象//2.传统的写法,写一个类实现该接口并创建对象//3.如果Tiger/Dog类只使用一次,后面不再使用//4.可以使用匿名内部类来简化开发//5.tiger的编译类型? IA//6.tiger的运行类型? 就是匿名内部类 XXX => Outer04$1Outer04 outer04 = new Outer04();outer04.method();}
}
class Outer04 {private int n1 = 10;public void method(){/*底层匿名内部类:class Outer04$1 implements IA{@Overridepublic void cry() {System.out.println("老虎在哭....");}}*///7.jdk底层在创建了匿名内部类Outer04$1,立即马上就创建了Outer04$1的实例,并且把地址//返回给tiger//8.匿名内部类Outer04$1使用一次,就不能使用tiger实例可以使用多次IA tiger = new IA(){@Overridepublic void cry() {System.out.println("老虎在哭....");}};tiger.cry();System.out.println("tiger的运行类型=" + tiger.getClass().getName());}
}interface IA {//接口public void cry();
}
//class Tiger implements IA{//    @Override
//    public void cry() {//        System.out.println("老虎在哭....");
//    }
//}
//class Dog implements IA{//    @Override
//    public void cry() {//        System.out.println("小狗在哭....");
//    }
//}
class Father {//类public Father(String name){//构造器}public void test(){}
}
结果:
老虎在哭....
tiger的运行类型=com.cheng.innerclass.Outer04$1

2.基于类的匿名内部类

//演示基于类的匿名内部类
//分析
//1.father编译类型: Father
//2.运行类型: Outer04$2
//3.底层会产生匿名内部类Outer04$2
/*class Outer04$2 extends Father{@Overridepublic void test() {System.out.println("匿名内部类重写了test方法");}}*/
//4.同时也直接返回了匿名内部类Outer04$2的对象
Father father = new Father("jack"){@Overridepublic void test() {System.out.println("匿名内部类重写了test方法");}
};
System.out.println("father对象的运行类型="+father.getClass().getName());
father.test();
{/*底层匿名内部类:class Outer04$1 implements IA{@Overridepublic void cry() {System.out.println("老虎在哭....");}}*///7.jdk底层在创建了匿名内部类Outer04$1,立即马上就创建了Outer04$1的实例,并且把地址//返回给tiger//8.匿名内部类Outer04$1使用一次,就不能使用IA tiger = new IA(){@Overridepublic void cry() {System.out.println("老虎在哭....");}};tiger.cry();System.out.println("tiger的运行类型=" + tiger.getClass().getName());//演示基于类的匿名内部类//分析//1.father编译类型: Father//2.运行类型: Outer04$2//3.底层会产生匿名内部类Outer04$2/*class Outer04$2 extends Father{@Overridepublic void test() {System.out.println("匿名内部类重写了test方法");}}*///4.同时也直接返回了匿名内部类Outer04$2的对象//5.注意("jack") 参数列表会传递给构造器Father father = new Father("jack"){@Overridepublic void test() {System.out.println("匿名内部类重写了test方法");}};System.out.println("father对象的运行类型="+father.getClass().getName());father.test();//基于抽象类的匿名内部类Animal animal = new Animal(){@Overridevoid eat() {System.out.println("小狗吃骨头...");}};animal.eat();System.out.println("animal对象的运行类型="+animal.getClass().getName());}
结果:
father对象的运行类型=com.cheng.innerclass.Outer04$2
匿名内部类重写了test方法
小狗吃骨头...
animal对象的运行类型=com.cheng.innerclass.Outer04$3

匿名内部类细节

匿名内部类既是一个类的定义,同时它本身也是一个对象,因此从语法上看,它既有定义类的特征,也有对象的特征

public class AnonymousInnerClassDetail01 {public static void main(String[] args) {Outer05 outer05 = new Outer05();outer05.f1();}
}
class Outer05{private int n1 = 99;public void f1(){//1.创建一个基于类的匿名内部类Person person = new Person(){@Overridepublic void hi() {//3.可以访问外部类的所有成员,包括私有成员System.out.println("匿名内部类重写了hi方法"+n1);}};person.hi();//运行时动态绑定,运行类型是Outer05&1//2.也可以直接调用,匿名内部类本身也是返回一个对象//4.不能添加访问修饰符,因为他的地位就是一个局部变量//5.作用域:仅仅在定义他的方法或代码块中//6.匿名内部类---->访问---->外部成员[访问方式:直接访问]//7.如果外部类和匿名局部内部类的成员重名时,如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问new Person(){@Overridepublic void hi() {System.out.println("匿名内部类重写了hi方法,哈哈哈");}@Overridepublic void ok(String str) {super.ok(str);}}.ok("123");}
}
class Person{//类public void hi(){System.out.println("Person hi()");}public void ok(String str){System.out.println("Person ok()" + str);}
}
//抽象类/接口...都可以写

匿名内部类的实践

  • 将匿名内部类当做实参传递,简洁高效
public class InterfaceClassExercise01 {public static void main(String[] args) {//将匿名内部类当做实参传递,简洁高效(只使用一次更加方便)f1(new IL() {@Overridepublic void show() {System.out.println("这是一幅名画");}});//传统方式,(多次使用更加方便,形式比较统一)f1(new Picture());}//静态方法,形参是接口类型public static void f1(IL il){il.show();}
}
interface IL{void show();
}
//类->实现IL =>编程领域称为(硬编码)
class Picture implements  IL{@Overridepublic void show() {System.out.println("传统方法...");}
}

小练习

public class InnerClassExercise02 {public static void main(String[] args) {CellPhone cellPhone = new CellPhone();//1.传递的是实现了Bell接口的匿名内部类//2.重写了 ring//3.cellPhone.alarmclock(new Bell() {@Overridepublic void ring() {System.out.println("懒猪起床了");}});cellPhone.alarmclock(new Bell() {@Overridepublic void ring() {System.out.println("你这个年纪你怎么能睡得着的");}});}
}
interface Bell{void ring();
}
class CellPhone{public void alarmclock(Bell bell){//形参是接口类型bell.ring();//动态绑定机制和运行类型绑定}}
public class Homework04 {public static void main(String[] args) {Cellphone cellphone = new Cellphone();cellphone.testwork(new Icalculate() {//会转到下方的double result = icalculate.work(n1,n2);//动态绑定@Overridepublic double work(double n1, double n2) {return n1 + n2;}},10,8);}
}
interface Icalculate{public double work(double n1,double n2);
}
class Cellphone{public void testwork(Icalculate icalculate,double n1,double n2){double result = icalculate.work(n1,n2);//动态绑定System.out.println("输出计算结果:" + result);}
}

3.成员内部类

public class MemberInnerClass01 {public static void main(String[] args) {Outer08 outer08 = new Outer08();outer08.t1();//外部其他类使用成员内部类的三种方式//1.实际上是new Inner08();但是Inner08在outer08里面,相当于把 new Inner08()当做是Outer08的属性//就是一个语法,不需要纠结Outer08.Inner08 inner08 = outer08.new Inner08();inner08.say();//2.在外部类中编写一个方法 可以返回Inner08对象Outer08.Inner08 inner08Instance = outer08.getInner08Instance();inner08Instance.say();}
}class Outer08{//外部类private int n1 = 10;public String name = "张三";public void hi(){System.out.println("hi");}//2.可以添加任意的访问修饰符public class Inner08{//1.成员内部类,定义在外部类的成员位置上private double sal = 99.8;private int n1 = 66;public void say(){//可以直接访问外部类的所有成员,包含私有//如果成员内部类的成员和外部类的成员重命,会遵守就近原则//可以通过  外部类名.this.属性 来访问外部类成员System.out.println("n1= "+ n1 +" name= "+name +"外部类的n1= "+Outer08.this.n1);hi();}}public Inner08 getInner08Instance(){return new Inner08();}public void t1(){//使用成员内部类Inner08 inner08 = new Inner08();inner08.say();}
}

4.静态内部类

静态内部类是定义在外部类的成员位置,并且有static修饰

1.可以直接访问外部类的所有静态成员,包含私有的,但不能直接访问非静态成员

2.可以添加任意访问修饰符,因为他的地位就是一个成员

3.作用域:同其他的成员,为整个类体

public class StaticInnerClass01 {//外部其他类public static void main(String[] args) {Outer10 outer10 = new Outer10();outer10.m1();//外部其他类使用静态内部类//方式一//静态内部类是通过类名直接访问Outer10.Inner10 inner10 = new Outer10.Inner10();inner10.say();//方式二//编写一个方法,可以返回一个静态内部类的实例,Outer10.Inner10 inner101 = outer10.getInner10();System.out.println("========");inner10.say();//方式三,通过外部类名直接访问方法Outer10.Inner10 inner10_ = Outer10.getInner10_();System.out.println("********");inner10_.say();}
}
class Outer10{//外部类private int n1 = 10;private static String name = "张三";private static void cry(){}//Inner10就是静态内部类//1.可以直接访问外部类的所有静态成员,包含私有的,但不能直接访问非静态成员//2.可以添加任意访问修饰符,因为他的地位就是一个成员//3.作用域:同其他的成员,为整个类体//4.内部类和外部类重命,通过外部类名.成员名static class Inner10{private static String name = "贾宝玉";public void say(){System.out.println(name+"外部name= "+Outer10.name);cry();}}public void m1(){//Outer10的一个方法//4.外部类--->访问--->静态内部类 访问方式:创建对象,再访问Inner10 inner10 = new Inner10();inner10.say();}public Inner10 getInner10(){return new Inner10();}//静态的public static Inner10 getInner10_(){return new Inner10();}
}

8.枚举类

枚举类的值不能够再改变

1.自定义枚举类

public class Ennumeration02 {public static void main(String[] args) {System.out.println(Season.SPRING);}
}
class Season{//类private String name;private String describe;//描述public static  final Season SPRING = new Season("春天", "温暖");public static  final Season SUMMER= new Season("夏天", "炎热");public static  final Season AUTUMN =new Season("秋天", "凉爽");public static  final Season WINTER = new Season("冬天", "寒冷");//1.将构造其私有化,目的:防止直接new//2.去掉set方法,防止修改属性//3.在类的内部创建固定对象//4.加final 在底层优化private Season(String name, String describe) {this.name = name;this.describe = describe;}public String getName() {return name;}public String getDescribe() {return describe;}@Overridepublic String toString() {return "Season{" +"name='" + name + '\'' +", describe='" + describe + '\'' +'}';}
}

2.关键字实现枚举

基本语法:

public class Ennumeration03 {public static void main(String[] args) {System.out.println(Season2.AUTUMN);System.out.println(Season2.SUMMER);}
}
enum Season2{//类//    public static  final Season SPRING = new Season("春天", "温暖");
//    public static  final Season SUMMER= new Season("夏天", "炎热");
//    public static  final Season AUTUMN =new Season("秋天", "凉爽");
//    public static  final Season WINTER = new Season("冬天", "寒冷");//使用enum来实现枚举类//1.使用关键字enum来代替class//2.public static  final Season SPRING = new Season("春天", "温暖") 直接使用//SPRING("春天", "温暖")//3.若有多个常量(对象),使用逗号间隔即可//4.先定义SPRING("春天", "温暖"),在定义属性private String name;SPRING("春天", "温暖"),WINTER("冬天", "寒冷"),SUMMER("夏天", "炎热"),AUTUMN("秋天", "凉爽");private String name;private String describe;//描述private Season2(String name, String describe) {//构造器this.name = name;this.describe = describe;}public String getName() {return name;}public String getDescribe() {return describe;}@Overridepublic String toString() {return "Season{" +"name='" + name + '\'' +", describe='" + describe + '\'' +'}';}
}

3.枚举类注意事项

javap

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-USJBG2V8-1665747352546)(E:\学习笔记\图片\未命名文件 (3)].png)

1.使用enum关键字开发一个工具类时,默认会继承Enum类,而且是一个final类,使用javap来验证

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p6md2tN7-1665747352546)(E:\学习笔记\图片\Snipaste_2022-04-27_12-51-44.jpg)]

2.传统的 public static final Season SPRING = new Season(“春天”, “温暖”);简化成SPRING(“春天”, “温暖”),必须知道它调用的是哪一个构造器

3.如果使用无参构造器创建枚举对象,则实参列表和小括号都可以省略

SPRING("春天", "温暖"),WINTER("冬天", "寒冷"),SUMMER("夏天", "炎热"),AUTUMN("秋天", "凉爽"),SEASON_2;private Season2(){//无参构造器}private Season2(String name, String describe) {//构造器this.name = name;this.describe = describe;}

4.当有多个枚举对象时,使用,间隔。最后有一个分号

5.枚举对象必须放在枚举类的行首

4.Enum常用方法

public class EnumMethod {public static void main(String[] args) {//使用Season2 枚举类各种方法Season2 autumn = Season2.AUTUMN;//1.输出枚举对象的名称System.out.println(autumn.name());//2.autumn.ordinal()输出的是该枚举对象的次序/从0开始遍历System.out.println(autumn.ordinal());//3.从反编译可以看到有一个values 方法,返回Season2[]//含有定义的所有枚举对象Season2[] values = Season2.values();for(Season2 season2:values){//增强for循环,迭代器System.out.println(season2);}//4.valueOf将字符串转换成枚举对象,要求字符串中必须为已有的常量名,否则报异常//1.根据你输入的"AUTUMN" 到Season2枚举对象去查找//2.如果找到了,就返回,如果没有找到,就报错Season2 autumn1 = Season2.valueOf("AUTUMN");System.out.println("autumn1="+autumn1);//autumn和autumn1是同一个对象System.out.println(autumn == autumn1);//5.compareTo:比较两个枚举常量,比较的是编号,结果是下标值相减/* public final int compareTo(E o) {Enum<?> other = (Enum<?>)o;Enum<E> self = this;if (self.getClass() != other.getClass() && // optimizationself.getDeclaringClass() != other.getDeclaringClass())throw new ClassCastException();return self.ordinal - other.ordinal;}*/System.out.println(Season2.AUTUMN.compareTo(Season2.SUMMER));}
}

5.Enum实现接口

public class EnnumerationDetail01 {public static void main(String[] args) {Music.CLASSICMUSIC.playing();}
}class A{}
//enum实现的类不能继承但可以实现接口
enum Music implements IPlaying{CLASSICMUSIC;@Overridepublic void playing() {System.out.println("播放音乐");}
}
interface IPlaying{public void playing();
}

9.注解

1.注解的理解

  • Annotation也被称为元数据(Metadata),用于修饰解释 包、类、方法、属性、构造器、局部变量等数据信息
  • 和注释一样,注解不影响程序逻辑,但注解可以被编译或运行,相当于嵌入在代码中的补充信息
  • 在JavaSE中,注解的使用目的比较简单,例如标记过时的功能,忽略警告等。在JavaEE中注解占据了更重要的角色,例如用来配置应用程序的任何切面,代替java EE旧版中所有遗留的繁冗代码和XML配置等

2.@overide

class Father{public void fly(){System.out.println("Father fly...");}public void say(){}
}
class Son extends Father{//1.@Override 注解放在fly上,表示fly方法重写了父类的fly方法//2.如果没有写 @Override还是重写了父类 fly//3.如果写了 @Override注解,编译器就会去检查该方法是否真的重写了父类方法//如果的确重写了,责编已通过,如果没有构成重写,则编译出错@Overridepublic void fly() {System.out.println("Son fly");}@Overridepublic void say(){}
}

@interface 不是interface,是注解类

@Target是修饰注解的注解,称为元注解

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lRUeOAWV-1665747352547)(E:\学习笔记\图片\Snipaste_2022-04-28_17-31-48.jpg)]

3.@Deprecated

public class Deprecated_ {public static void main(String[] args) {A a = new A();a.hi();}
}
//1.@Deprecated 修饰某个元素,表示该元素已经过时
//2.即不再推荐使用,仍然可以使用
//3.查看 @Deprecated 注解类的源码
//4.可以修饰方法,类,字段,包,参数 等等
//5.@Deprecated可以做到新旧版本的兼容和过渡
@Deprecated
class A {public int n1 = 10;@Deprecatedpublic void hi(){}
}

4.@SuppressWarning

all,抑制所有警告
boxing,抑制与封装/拆装作业相关的警告
cast,抑制与强制转型作业相关的警告
dep-ann,抑制与淘汰注释相关的警告
deprecation,抑制与淘汰的相关警告
fallthrough,抑制与switch陈述式中遗漏break相关的警告
finally,抑制与未传回finally区块相关的警告
hiding,抑制与隐藏变数的区域变数相关的警告
incomplete-switch,抑制与switch陈述式(enum case)中遗漏项目相关的警告
javadoc,抑制与javadoc相关的警告
nls,抑制与非nls字串文字相关的警告
null,抑制与空值分析相关的警告
rawtypes,抑制与使用raw类型相关的警告
resource,抑制与使用Closeable类型的资源相关的警告
restriction,抑制与使用不建议或禁止参照相关的警告
serial,抑制与可序列化的类别遗漏serialVersionUID栏位相关的警告
static-access,抑制与静态存取不正确相关的警告
static-method,抑制与可能宣告为static的方法相关的警告
super,抑制与置换方法相关但不含super呼叫的警告
synthetic-access,抑制与内部类别的存取未最佳化相关的警告
sync-override,抑制因为置换同步方法而遗漏同步化的警告
unchecked,抑制与未检查的作业相关的警告
unqualified-field-access,抑制与栏位存取不合格相关的警告
unused,抑制与未用的程式码及停用的程式码相关的警告

//1.当我们不希望看到这些警告的时候,可以使用SupressWarnings注解来抑制警告信息//2.在{""}中,可以写入希望抑制(不显示)的警告信息//3.关于SuppressWarnings 作用范围是和你放置的位置相关//通常我们可以放置具体语句,方法,类//@SuppressWarnings源码//该注解类有数组 String[] value();设置一个数组,比如{"rawtypes","unchecked","unused"}//@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})//@Retention(RetentionPolicy.SOURCE)//public @interface SuppressWarnings {//    String[] value();//}@SuppressWarnings("all")public static void main(String[] args) {List list = new ArrayList();list.add("jack");list.add("tom");list.add("mary");int i;System.out.println(list.get(1));}@SuppressWarnings({"rawtypes","unchecked","unused"})public void f1(){List list = new ArrayList();list.add("jacky");list.add("tom");list.add("mary");int i;System.out.println(list.get(1));}
}

5.JDK的元Annotation(元注解,了解)

  • 元注解的基本介绍:

JDK的元Annotation用于修饰其他的Annotation

  • 元注解的种类
  1. Retention //指定注解的作用范围,三种SOURCEC CLASS RUNTIME
  2. Target //指定注解可以用在哪些地方
  3. Documented //指定该注解是否会在javadoc中体现
  4. Inherited //子类会继承父类的注解

10.异常处理

1.基本介绍

  • 程序运行时,发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常。异常发生时,是任程序自生自灭,立刻退出终止。在Java中即,Java在编译或运行或者运行过程中出现的错误。

  • 异常处理机制能让程序在异常发生时,按照代码的预先设定的异常处理逻辑,针对性地处理异常,让程序尽最大可能恢复正常并继续执行,且保持代码的清晰。

  • Java中的异常可以是函数中的语句执行时引发的,也可以是程序员通过throw 语句手动抛出的,只要在Java程序中产生了异常,就会用一个对应类型的异常对象来封装异常,JRE就会试图寻找异常处理程序来处理异常。

  • Throwable类是Java异常类型的顶层父类,一个对象只有是 Throwable 类的(直接或者间接)实例,他才是一个异常对象,才能被异常处理机制识别。JDK中内建了一些常用的异常类,我们也可以自定义异常。

  • 执行过程中所发生的异常事件可分为两大类

  1. Error(错误):java虚拟机无法解决的严重问题。如JVM内部错误,资源耗尽等等
  2. Exception:其他因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理。例如空指针访问,试图读取不存在的文件 Exception又分为两大类==:运行时异常[程序运行时发生的异常]和编译异常[编译时,编译器检查出异常]==
  3. 运行时异常:
  4. 编译异常:

2.入门语法

public class Exception01 {public static void main(String[] args) {int num1=10;int num2=0;//选中可能发生异常语句num1/num2 ctrl+alt+t快捷键try {int res = num1/num2;} catch (Exception e) {//            e.printStackTrace();System.out.println(e.getMessage());//输出异常内容}System.out.println("程序继续运行");}
}结果:
/ by zero
程序继续运行

3.异常体系图

常见的运行时异常:

1.NullPointerException:空指针异常

当应用程序试图在需要对象的地方使用 null时,抛出异常

public static void main(String[] args) {String name = null;System.out.println(name.length());
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3eYsAred-1665747352547)(E:\学习笔记\图片\Snipaste_2022-04-29_15-59-33.jpg)]

2.ArithmeticException数学运算异常

当程序出现异常的运算条件时,抛出此异常。例如,一个整数"除以零"时,抛出此类的一个实例

3.ArrayIndexOutOfBoundsException数组越界异常

4.ClassCastException类型转换异常

父类可以指向子类的对象即

A b = new B();//向上转型
B b1 = (B)b;//向下转型(强制类型转换)
class A{}
class B extends A{}
class C extends A{}

子类不可以指向父类的对象即 下方是错误的

​ B a = new A();

编译不会出错,但是运行时会出现ClassCastException类型转换异常

C c2 = (C)b;

5.NumberFormatException数字格式不正确异常

将字符串转换为数字,但该字符串不能转换抛出此异常

public class Exception02 {public static void main(String[] args) {String name = "程冠希";//将string转换为intint num = Integer.parseInt(name);System.out.println(num);}
}

常见的编译期异常:

编译异常是指在编译期间就必须处理的异常,否则代码不能通过编译

1.ClassNotFoundException(类找不到异常)

2.FileNotFoundException(编译文件夹中找不到,就是发布到tomcat中的,不是工程中)

3.SQLException :提供有关数据库访问错误或其他错误的信息的异常。( 比如SQL语句写错,访问的表不存在,连接数据库失败等等)

4.IOexception:IO流异常。一般在读写数据的时候会出现这种问题。

5.EOFException:当输入过程中意外到达文件或流的末尾时,抛出此异常。

4.异常处理机制

1.try/catch

public static void main(String[] args) {try {可能有异常的代码}catch (Exception e){捕获到异常1.当异常发生时,系统将异常封装成Exception 对象e,传递给catch2.得到异常后可自行处理,例如打印异常3.如果没有发生异常,catch代码块不执行}finally {1.不管try代码块是否有异常都要执行finally2.通常将释放资源的代码放在finally}
}

2.throws

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L83jYTQa-1665747352548)(E:\学习笔记\图片\未命名文件.png)]

方法二出现异常可以throw到调用它的方法让方法一处理,如果都不处理就返回到JVM这时JVM继续摆烂,直接输出异,中断程序

  • 如果没有显示使用哪一种处理机制默认是throws

一.try-catch异常处理细节

public static void main(String[] args) {//1.如果异常发生了,则异常发生后面的代码不会执行,直接进入到catch块//2.如果异常没有发生,则顺序执行try的代码块,不会进入到catch//3.如果希望不管是否发生异常,都执行某段代码(比如关闭连接,释放资源等)则使用如下代码-finallytry {String name = "程冠希";//将string转换为intint num = Integer.parseInt(name);System.out.println(num);} catch (NumberFormatException e) {System.out.println("异常信息:"+e.getMessage());} finally {System.out.println("finally代码块被执行");}
}

4.如果try代码块有可能有多个异常可以使用多个catch分别捕获不同的异常,相应处理

要求子类异常写在前面,父类异常写在后面

public class Exception02 {public static void main(String[] args) {//1.如果try代码块有可能有多个异常//可以使用多个catch分别捕获不同的异常,相应处理//要求子类异常写在前面,父类异常写在后面try {Person person = new Person();person = null;System.out.println(person.getName());int n1 = 10;int n2 = 0;int res = n1/n2;} catch (NullPointerException e) {System.out.println(e.getMessage());}catch (ArithmeticException e){System.out.println(e.getMessage());}finally {System.out.println("执行finally代码块");}}
}
class Person{String name;public String getName() {return name;}
}
//没有抛出ArithmeticException异常,因为程序到 System.out.println(person.getName());就终止了
null
执行finally代码块

5.只有try-finally相当于没有捕获异常

这样执行完finally代码块的内容就会结束,目的是为了释放资源

public static void main(String[] args) {try {int n1 = 10;int n2 = 0;System.out.println(n1/n2);} finally {System.out.println("执行了finally");}System.out.println("程序继续执行");//此语句不再执行
}
执行了finally

二、throws异常处理细节

1.入门语法

public class Exception02 {public static void main(String[] args) {}//抛出异常public void f2() throws FileNotFoundException {//创建了一个文件流对象FileInputStream fileInputStream = new FileInputStream("d://aa.txt");}
}

2.细节

  • 对于编译异常,程序中必须处理,比如 try-catch 或者 throws
  • 对于运行时异常,程序中如果没有处理,默认就是 throws 的方式处理
  • 子类重写父类的方法时,对抛出异常的规定:子类重写的方法,所抛出的异常类型要么和父类抛出的异常一致,要么为父类抛出的异常的类型的子类型
  • throws 过程中,如果有方法 try-catch ,就相当于处理异常,就可以不必 throws

throws的细节实现跳过了,接下来就是java的常用类介绍了

一些碎碎念:

都在说互联网越来越卷了,动起来吧,总比摆烂强,一定要找准自己的方向,不一定要是java,java人确实多,考研也好就业也罢,总得先有个保底的,不然应届生身份没有了就很难受。

希望看到这篇文章的你能动起来加油吧!!

Java学习(入门知识)相关推荐

  1. JAVA学习入门2---计算机基础知识

    1.计算机概述 1.1什么是计算机? 计算机(Computer)全称:电子计算机,俗称电脑.是一种能够按照程序运行,自动.高速处理海量数据的现代化智能电子设备.由硬件和软件所组成,没有安装任何软件的计 ...

  2. Java基础入门知识

    以下是学习java必备的知识 目录 前言 一.Java入门 二.基本数据类型与数组 标识符与关键字 2. 基本数据类型 3. 类型转换运算 4. 运算符 5. 数组 6.控制结构(与c使用一致) 总结 ...

  3. JAVA学习基础知识(一)JDK的安装和配置及Java的发展历史

    前言 欢迎阅读本系列文章,本文主要内容为Java的发展历史,以及在电脑上如何配置Java环境.ps:这是第一次发布java语言的文章,若出现错误,望指正. 文章目录 前言 java的发展历史 Java ...

  4. 适合零基础的Java基础入门知识(部分,后续会不断更新)-看后觉得不错,请点赞收藏-咱们一起进步

    JAVA入门 打开CMD Win+R 输入cmd. 按下回车键 Win+E 打开我的电脑 常见CMD命令 盘符名称+冒号 说明:盘符切换 举例:E:回车,表示切换到E盘 dir 说明:查看当前路径下的 ...

  5. 强化学习入门知识与经典项目分析1.3

    Python微信订餐小程序课程视频 https://edu.csdn.net/course/detail/36074 Python实战量化交易理财系统 https://edu.csdn.net/cou ...

  6. Java学习预科知识

    预科知识 什么是计算机 Computer:全称电子计算机,俗称电脑 能够按照程序运行,自动.高速处理海量数据的现代化之恶能电子设备. 由硬件和软件组成 常见的形式有计算机.笔记本计算机.大型计算机等 ...

  7. Java学习——基础知识之运算符和输入输出

    知识是珍宝,但实践是得到它的钥匙.--托马斯·富勒 Java基础知识之运算符和输入输出 一.运算符 1.算术运算符:包括:+,-,*,/(整数运算取整),%(取余),++(递增1),–等 2.赋值运算 ...

  8. Java学习进阶知识篇

    系列文章目录 提示:....................... 文章目录 系列文章目录 前言 一.类和对象 面向对象基本介绍 类的基本使用属性 构造方法和析构方法 对象 二. 总结 前言 提示:这 ...

  9. java学习入门怎么做最为高效

    如今的Java编程语言势头非常火爆,应用范围非常的广泛,已经是当下最火的行业之一,竞争力也是逐渐的增加,工资待遇非常丰厚,未来的发展也是极好的. 想学习Java编程加入IT行业,我们要怎么学? 如果你 ...

最新文章

  1. JWT的使用及登录账号
  2. lambdafiltermapreduce函数的基本使用
  3. OpenCV+Qt+CMake安装+十种踩坑
  4. 使用Struts2,Hibernate和MySQL BLOB开发个人迷你相册应用程序–第1部分
  5. Redis之Redis内存模型
  6. Linux 抓包工具:tcpdump
  7. uvc摄像头代码解析1
  8. SonarQube 8.4 发布,分析时间最多可减少 80%
  9. 海岸鸿蒙甲醇中8种苯系物,甲醇中8种苯系物混合溶液标准物质-8种VOC
  10. 2021-2025年中国云计费行业市场供需与战略研究报告
  11. GNN | 最新2022综述
  12. 【ACL2021】具有可解释的、鲁棒的、并具有泛化能力的三篇问答系统相关论文
  13. 关于Excel导入SQLServer的说明
  14. 如何将百度文库中不能复制的文字复制下来
  15. 1.3寸OLED 12864 sh1106带中文字库液晶屏介绍
  16. 推荐的开源 PHP CMS 系统
  17. Windows10安装韩语输入法详细教程(图文)
  18. [玩转UE4/UE5动画系统>技能系统(GAS)篇] 二 技能 Gameplay Ability(GA)
  19. 超简单详细小白双系统安装教程Win10+deepin
  20. DRAM战国时代 长江存储、联电、合肥长芯三大势力将对决

热门文章

  1. fgetc函数踩过的坑
  2. 1977年图灵奖--约翰·巴克斯简介
  3. C++简介 C语言编程原理
  4. 什么电脑录音软件是最好用的
  5. ArrayList和LinkedList的底层源码之我见
  6. 后台模拟页面登陆_微信直播小程序后台,微信朋友圈可直达小程序直播了
  7. 参考文献意译翻译借鉴
  8. 30系显卡能用服务器系统吗,买显卡吗 来看看适合自己的30系列显卡
  9. unity传统文化交互以及摄像头移动和旋转
  10. 3分钟拥有专属域名邮箱 / 腾讯云免费企业邮箱服务