JavaSE总结(三)

简介: JavaSE总结

抽象类和接口


抽象类


抽象类语法


  // 抽象类:被abstract修饰的类
public abstract class A {
  // 抽象方法:被abstract修饰的方法,没有方法体
  abstract public void fun();
  abstract void func();
  // 抽象类也是类,也可以增加普通方法和属性
  public double funcc(){
    return m;
  }
  protected double f;  
}

抽象类也是类,内部可以包含普通方法和属性,甚至构造方法


抽象类特性


  1. 抽象类不能直接实例化对象
  2. 抽象方法不能是 private 的
  3. 抽象方法不能被final和static修饰,因为抽象方法要被子类重写
  4. 抽象类必须被继承,并且继承后子类要重写父类中的抽象方法,否则子类也是抽象类,必须要使用 abstract 修饰
  5. 抽象类中不一定包含抽象方法,但是有抽象方法的类一定是抽象类
  6. 抽象类中可以有构造方法,供子类创建对象时,初始化父类的成员变量


抽象类作用


抽象类本身不能被实例化, 要想使用, 只能创建该抽象类的子类, 然后让子类重写抽象类中的抽象方法,使用抽象类相当于多了一重编译器的校验。


接口


接口语法


public interface 接口名称,接口名称...{  //可以实现多个接口
  // 抽象方法
  public abstract void method1(); // public abstract 是固定搭配,可以不写
  public void method2();
  abstract void method3();
  void method4();
  // 注意:在接口中上述写法都是抽象方法,少写固定搭配让代码更简洁
}


接口使用


接口不能直接使用,必须要有一个"实现类"来"实现"该接口,实现接口中的所有抽象方法

注意:子类和父类之间是extends 继承关系,类与接口之间是 implements 实现关系。


接口间的继承


类和类之间是单继承的,一个类可以实现多个接口,接口与接口之间可以多继承。即:用接口可以达到多继承的目的。

接口可以继承一个接口, 达到复用的效果. 使用 extends 关键字。

接口间的继承相当于把多个接口合并在一起,不需要去实现接口中的方法。


接口特性


  1. 接口类型是一种引用类型,但是不能直接new接口的对象
  2. 接口中每一个方法都是public的抽象方法, 即接口中的方法会被隐式的指定为 public abstract(只能是public abstract,其他修饰符都会报错)
  1. 接口中的方法是不能在接口中实现的,只能由实现接口的类来实现
  1. 重写接口中方法时,不能使用默认的访问权限 (因为接口中的方法默认为 public abstract)
  1. 接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量
  1. 接口中不能有静态代码块和构造方法
  1. 接口虽然不是类,但是接口编译完成后字节码文件的后缀格式也是.class
  1. 如果类没有实现接口中的所有的抽象方法,则类必须设置为抽象类
  1. jdk8中:接口中还可以包含default方法


注意 :

一个类可以实现多个接口 (继承是只能继承一个)

一个类实现多个接口时,每个接口中的抽象方法都要实现,否则类必须设置为抽象类。( IDEA 中使用 ctrl + i 快速实现接口)


抽象类和接口的区别


核心区别:

抽象类中可以包含普通方法和普通字段, 这样的普通方法和字段可以被子类直接使用(不必重写), 而接口中不能包含普通方法, 子类必须重写所有的抽象方法.

49b79432240b44b3a8b052ecc85106f3.png


String


字符串构造的常用三种方法


public static void main(String[] args) {
  // 使用常量串构造
  String s1 = "hello world";
  System.out.println(s1);
  // 直接newString对象
  String s2 = new String("hello world");
  System.out.println(s1);
  // 使用字符数组进行构造
  char[] array = {'h','e','l','l','o','w','o','r','l','d'};
  String s3 = new String(array);
  System.out.println(s1);
}


String对象的比较


1.比较是否引用同一个对象

对于内置类型,== 比较的是变量中的值;对于引用类型,比较的是引用中的地址。


  1. boolean equals(Object anObject) 方法:按照字典序比较(字符大小的顺序)

String类重写了父类Object中equals方法,Object中equals默认按照==比较,String重写equals方法后,按照如下规则进行比较,比如: s1.equals(s2)


public boolean equals(Object anObject) {
// 1. 先检测this 和 anObject 是否为同一个对象比较,如果是返回true
  if (this == anObject) {
  return true;
  } 
// 2. 检测anObject是否为String类型的对象,如果是继续比较,否则返回false
  if (anObject instanceof String) {
// 将anObject向下转型为String类型对象
  String anotherString = (String)anObject;
  int n = value.length;
// 3. this和anObject两个字符串的长度是否相同,是继续比较,否则返回false
  if (n == anotherString.value.length) {
    char v1[] = value;
    char v2[] = anotherString.value;
    int i = 0;
// 4. 按照字典序,从前往后逐个字符进行比较
    while (n-- != 0) {
    if (v1[i] != v2[i])
    return false;
    i++;
    } 
    return true;
  }
  }
  return false;
}
  1. int compareTo(String s) 方法: 按照字典序进行比较

与equals不同的是,equals返回的是boolean类型,而compareTo返回的是int类型。具体比较方式:


  1. 先按照字典次序大小比较,如果出现不等的字符,直接返回这两个字符的大小差值
  2. 如果前k个字符相等(k为两个字符长度最小值),返回值两个字符串长度差值
public static void main(String[] args) {
  String s1 = new String("abc");
  String s2 = new String("ac");
  String s3 = new String("abc");
  String s4 = new String("abcdef");
  System.out.println(s1.compareTo(s2)); // 不同输出字符差值-1
  System.out.println(s1.compareTo(s3)); // 相同输出 0
  System.out.println(s1.compareTo(s4)); // 前k个字符完全相同,输出长度差值 -3
}
  1. int compareToIgnoreCase(String str) 方法:与compareTo方式相同,但是忽略大小写比较
public static void main(String[] args) {
  String s1 = new String("abc");
  String s2 = new String("ac");
  String s3 = new String("ABc");
  String s4 = new String("abcdef");
  System.out.println(s1.compareToIgnoreCase(s2)); // 不同输出字符差值-1
  System.out.println(s1.compareToIgnoreCase(s3)); // 相同输出 0
  System.out.println(s1.compareToIgnoreCase(s4)); // 前k个字符完全相同,输出长度差值 -3
}


StringBuilder和StringBuffer


由于String的不可更改特性,为了方便字符串的修改,Java中又提供StringBuilder和StringBuffer类。这两个类大部分功能是相同的.


String和StringBuilder最大的区别在于String的内容无法修改,而StringBuilder的内容可以修改。频繁修改字符串的情况考虑使用StringBuilder.


注意:String和StringBuilder类不能直接转换。如果要想互相转换,可以采用如下原则:

String变为StringBuilder: 利用StringBuilder的构造方法或append()方法

StringBuilder变为String: 调用toString()方法


String、StringBuffer、StringBuilder的区别:


String的内容不可修改,StringBuffer与StringBuilder的内容可以修改.

StringBuffer与StringBuilder大部分功能是相似的

StringBuffer采用同步处理,属于线程安全操作;而StringBuilder未采用同步处理,属于线程不安全操作


异常


异常的体系结构


异常种类繁多,为了对不同异常或者错误进行很好的分类管理,Java内部维护了一个异常的体系结构:

9cb029aaf7c94f139724a60b37aee09e.png


  1. Throwable:是异常体系的顶层类,其派生出两个重要的子类, Error 和 Exception
  2. Error:指的是Java虚拟机无法解决的严重问题,比如:JVM的内部错误、资源耗尽等,典型代表:
  3. StackOverflowError和OutOfMemoryError,一旦发生回力乏术。
  4. Exception:异常产生后程序员可以通过代码进行处理,使程序继续执行。比如:感冒、发烧。我们平时所说的异常就是Exception。


异常分类


  1. 编译时异常

在程序编译期间发生的异常,称为编译时异常,也称为受查异常

  1. 运行时异常

在程序执行期间发生的异常,称为运行时异常,也称为非受查异常

RunTimeException以及其子类对应的异常,都称为运行时异常。比如:NullPointerException、ArrayIndexOutOfBoundsException、ArithmeticException。


异常抛出


借助throw关键字,抛出一个指定的异常对象,将错误信息告知给调用者。


throw new XXXException("异常产生的原因");


注意:


  1. throw必须写在方法体内部
  2. 抛出的对象必须是Exception 或者 Exception 的子类对象
  3. 如果抛出的是 RunTimeException 或者 RunTimeException 的子类,则可以不用处理,直接交给JVM来处理
  4. 如果抛出的是编译时异常,用户必须处理,否则无法通过编译
  5. 异常一旦抛出,其后的代码就不会执行


异常的捕获


主要有两种:异常声明throws 以及 try-catch捕获处理。


异常声明throws


处在方法声明时参数列表之后,当方法中抛出编译时异常,用户不想处理该异常,此时就可以借助throws将异常抛给方法的调用者来处理。即当前方法不处理异常,提醒方法的调用者处理异常。


修饰符 返回值类型 方法名(参数列表) throws 异常类型1,异常类型2...{
}    //可以声明多个异常


注意:


  1. throws必须跟在方法的参数列表之后
  2. 声明的异常必须是 Exception 或者 Exception 的子类
  3. 方法内部如果抛出了多个异常,throws之后必须跟多个异常类型,之间用逗号隔开,如果抛出多个异常类型具有父子关系,直接声明父类即可。
  4. 调用声明抛出异常的方法时,调用者必须对该异常进行处理,或者继续使用throws抛出


try-catch捕获并处理


throws对异常并没有真正处理,而是将异常报告给抛出异常方法的调用者,由调用者处理。如果真正要对异常进行处理,就需要try-catch.


try{
// 将可能出现异常的代码放在这里
}catch(要捕获的异常类型 e){
// 如果try中的代码抛出异常了,此处catch捕获时异常类型与try中抛出的异常类型一致时,或者是try中抛出异常的基类时,就会被捕获到
// 对异常就可以正常处理,处理完成后,跳出try-catch结构,继续执行后序代码
}[catch(异常类型 e){
// 对异常进行处理
}finally{
// 此处代码一定会被执行到
}]
// 后序代码
// 当异常被捕获到时,异常就被处理了,这里的后序代码一定会执行
// 如果捕获了,由于捕获时类型不对,那就没有捕获到,这里的代码就不会被执行


注:


  1. [ ]中表示可选项,可以添加,也可以不用添加
  2. try中的代码可能会抛出异常,也可能不会

注意:


  1. try块内抛出异常位置之后的代码将不会被执行
  2. 如果抛出异常类型与catch时异常类型不匹配,即异常不会被成功捕获,也就不会被处理,继续往外抛,直到JVM收到后 中断程序----异常是按照类型来捕获的
  3. try中可能会抛出多个不同的异常对象,则必须用多个catch来捕获----即多种异常,多次捕获
  4. 可以通过一个catch捕获所有的异常,即多个异常,一次捕获(用它们的父类异常捕获,如果这样做我们就不知道发生了什么异常,因此不推荐)

在catch 语句里我们有三种处理异常方法:

只打印异常信息:System.out.println(e.getMessage());

打印异常类型,异常信息:System.out.println(e);

打印信息最全面:e.printStackTrace();


finally


try{
// 可能会发生异常的代码
}catch(异常类型 e){
// 对捕获到的异常进行处理
}finally{
// 此处的语句无论是否发生异常,都会被执行到
} 
// 如果没有抛出异常,或者异常被捕获处理了,这里的代码也会执行

finally中的代码一定会执行的,一般在finally中进行一些资源清理的扫尾工作。


自定义异常


Java 中虽然已经内置了丰富的异常类, 但是并不能完全表示实际开发中所遇到的一些异常,此时就需要维护符合我们实际情况的异常结构。


实现方式:


  1. 自定义异常类,然后继承自Exception 或者 RunTimeException
  2. 实现一个带有String类型参数的构造方法,参数含义:出现异常的原因

注意:

自定义异常通常会继承自 Exception 或者 RuntimeException

继承自 Exception 的异常默认是受查异常

继承自 RuntimeException 的异常默认是非受查异常


举个例子,实现一个用户登录功能:


public class Test {
    public static void fun(String name2, String code2) throws PasswordException, UsernameException {
        String name = "张三";
        String code = "666666";
        if(!name2.equals(name)) { //如果输入的姓名或密码错误,则抛出异常
            throw new PasswordException("用户名错误!");
        }
        if(!code2.equals(code)) {
            throw new UsernameException("密码错误!");
        }
        System.out.println("输入成功!!!");
    }
    public static void main(String[] args) throws PasswordException, UsernameException {
        Scanner scanner = new Scanner(System.in);
        String name = scanner.nextLine();
        String code = scanner.nextLine();
        fun(name,code);
    }
}


public class PasswordException extends Exception{
    public PasswordException(String message) {
        super(message);
    }
}


public class UsernameException extends Exception{
    public UsernameException(String message) {
        super(message);
    }
}

相关文章
|
自然语言处理 Java 编译器
【javaSE】 方法的使用
【javaSE】 方法的使用
|
3月前
|
Java Linux 编译器
JavaSE基础1
JavaSE基础
52 4
|
3月前
|
存储 Java
JavaSE基础2
JavaSE基础
41 1
|
Java 编译器
|
Java
总 JavaSE课程体系
总 JavaSE课程体系
57 0
|
6月前
|
缓存 NoSQL Java
JavaSE面试题(一)
JavaSE面试题(一)
JavaSE面试题(一)
|
6月前
|
安全 JavaScript Java
JavaSE面试题(二)
JavaSE面试题(二)
|
11月前
|
机器学习/深度学习 自然语言处理 Java
【JavaSE】方法的使用
【JavaSE】方法的使用
|
机器学习/深度学习 Java 编译器
方法的使用【JavaSE】
方法的使用【JavaSE】
35 0
|
Java 编译器
61.【JavaSE 《StudyKuang》】
61.【JavaSE 《StudyKuang》】
43 0