当前位置: 首页 > article >正文

厉兵秣马之Java 语言基础和进阶(二)

续写 厉兵秣马之Java 语言基础和进阶(一)

厉兵秣马之Java 语言基础和进阶(二)

  • 5. 抽象类
  • 6. 接口
  • 7. 抽象类与接口区别
  • 8. JAVA集合类的使用
      • 8.1. 列表(List)
      • 8.2. 集合(Set)
      • 8.3. 映射(Map)
      • 8.4. 队列(Queue)
      • 8.5. 其他集合类
      • 8.6. 迭代器(Iterator)
  • 9 JAVA包、内部类和匿名类
      • 9.1.包(Package)
      • 9.2. 内部类:
  • 10 数组
  • 11 字符串
  • 12.文件处理 Apache Commons IO
  • 13. JAVA异常类的使用
      • 13.1. 什么是异常?
      • 13.2. 创建自定义异常

5. 抽象类

抽象类是Java中一种不能被实例化的类,它通常包含抽象方法,这些方法没有具体的实现,需要在子类中被具体实现。抽象类是面向对象编程中抽象化的一种手段,它提供了一种方式来定义一组相关类共享的通用模板,同时强制要求子类实现某些方法。

抽象类的特点

  1. 不能实例化:你不能创建抽象类的对象。
  2. 可以包含抽象方法:抽象方法没有实现,需要在子类中被重写。
  3. 可以包含具体方法:抽象类可以包含已经实现的方法,这些方法可以被子类继承和使用。
  4. 可以有成员变量:抽象类可以有成员变量,这些变量可以是privateprotectedpublicstatic
  5. 可以被继承:其他类可以通过extends关键字继承抽象类,并提供抽象类中抽象方法的具体实现。

抽象类的使用

抽象类通常用于以下情况:

  • 当你想要定义一个通用模板,但不想允许直接创建该类的对象时。
  • 当你想要提供一个或多个方法的部分实现,并要求子类完成剩余部分时。
  • 当你想要强制子类遵循特定的协议或行为时。

示例

// 定义一个抽象类
abstract class Animal {
    // 抽象方法,没有实现
    abstract void makeSound();

    // 具体方法,已经被实现
    void eat() {
        System.out.println("This animal eats");
    }
}

// 继承抽象类并实现抽象方法
class Dog extends Animal {
    @Override
    void makeSound() {
        System.out.println("Dog barks");
    }
}

// 继承抽象类并实现抽象方法
class Cat extends Animal {
    @Override
    void makeSound() {
        System.out.println("Cat meows");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal myDog = new Dog(); // 合法,可以创建子类的实例
        myDog.makeSound(); // 输出: Dog barks
        myDog.eat(); // 输出: This animal eats

        // Animal myAnimal = new Animal(); // 非法,不能创建抽象类的对象
    }
}

在这个例子中,Animal是一个抽象类,它包含一个抽象方法makeSound和一个具体方法eatDogCat类继承自Animal类,并提供了makeSound方法的具体实现。在main方法中,我们可以创建DogCat的对象,但不能创建Animal的对象。

抽象类是Java中实现代码重用和确保子类遵循特定协议的有效方式。通过使用抽象类,你可以定义一个通用的模板,并通过子类来提供具体的实现,从而实现代码的灵活性和可扩展性。

6. 接口

接口可以理解为一种特殊的类,里面全部都是由全局常量和公共的抽象方法所组成
1.接口必须有子类,并且子类要实现全部的抽象方法
2.一个子类可以实现多个接口,但是一个子类只能继承一个抽象类
3.一个接口可以继承多个接口
4.一个子类可以继承抽象类同时实现接口

接口(Interface)在Java中是一种特殊的抽象类型,它是一组方法声明的集合,这些方法没有具体的实现。接口主要用于定义类必须遵守的契约或行为规范。接口是Java实现多态的一种机制,允许不同的类以自己的方式实现相同的方法。

接口的特点

  1. 抽象方法:接口中的方法默认是publicabstract的,这意味着它们没有实现,必须由实现接口的类来提供具体实现。
  2. 默认方法:从Java 8开始,接口可以包含默认方法(default方法),这些方法有实现,可以被实现类继承。
  3. 静态方法:接口也可以包含静态方法,这些方法可以直接通过接口调用,不需要实现。
  4. 常量:接口中可以定义常量,即public static final变量。
  5. 多重实现:一个类可以实现多个接口,这允许类具有多个类型的属性和行为。
  6. 继承:接口可以继承自一个或多个其他接口,这有助于代码的组织和重用。

接口的用途

接口主要用于以下目的:

  • 定义契约:接口定义了实现类必须遵守的规则和行为。
  • 实现多态:通过实现相同的接口,不同的类可以以不同的方式响应相同的方法调用。
  • 代码解耦:接口允许代码与具体实现分离,提高代码的灵活性和可维护性。
  • 扩展功能:通过实现不同的接口,类可以扩展其功能,而不需要修改现有的代码。

示例

// 定义一个接口
interface Flyable {
    void fly();
}

// 定义一个接口
interface Swimmable {
    void swim();
}

// 实现接口
class Bird implements Flyable {
    public void fly() {
        System.out.println("Bird is flying");
    }
}

class Fish implements Swimmable {
    public void swim() {
        System.out.println("Fish is swimming");
    }
}

// 多重实现
class Duck implements Flyable, Swimmable {
    public void fly() {
        System.out.println("Duck is flying");
    }

    public void swim() {
        System.out.println("Duck can also swim");
    }
}

public class Main {
    public static void main(String[] args) {
        Flyable myBird = new Bird();
        myBird.fly(); // 输出: Bird is flying

        Swimmable myFish = new Fish();
        myFish.swim(); // 输出: Fish is swimming

        Flyable myDuck = new Duck();
        myDuck.fly(); // 输出: Duck is flying
    }
}

在这个例子中,FlyableSwimmable是两个接口,它们定义了flyswim方法。BirdFish类分别实现了这些接口,而Duck类实现了两个接口,展示了多重实现的能力。

接口是Java中实现多态和定义契约的强大工具,它们使得代码更加灵活和可扩展。通过接口,Java程序可以轻松地适应变化,支持新的功能和行为。

7. 抽象类与接口区别

接口(Interface)和抽象类(Abstract Class)在Java中都是用于定义不能被实例化的类型,它们都可以包含抽象方法,但它们之间存在一些关键的区别:

  1. 继承限制

    • 一个类可以实现多个接口,但只能继承自一个抽象类或具体类。这使得接口成为实现多重继承的一种方式。
    • 抽象类可以继承自另一个抽象类或具体类。
  2. 方法实现

    • 接口中的所有方法默认都是抽象的,必须由实现接口的类提供具体实现。
    • 抽象类可以包含抽象方法和具体方法。抽象类中的抽象方法必须由子类实现,而具体方法可以直接使用。
  3. 构造方法

    • 接口不能包含构造方法,因为它们不能被实例化。
    • 抽象类可以包含构造方法,但这些构造方法不能从外部访问,只能被子类调用。
  4. 成员变量

    • 接口中的成员变量默认是public static final的,即它们是常量。
    • 抽象类中的成员变量可以是privateprotectedpublicstatic,并且可以不是final的。
  5. 实例化

    • 接口不能被实例化,但可以从接口类型引用变量指向实现该接口的具体类的实例。
    • 抽象类不能被直接实例化,但可以创建其实例的引用指向其子类的实例。
  6. 默认方法和静态方法

    • 从Java 8开始,接口可以包含默认方法(default方法),这些方法有默认实现,可以被子类覆盖。
    • 接口也可以包含静态方法,这些方法可以直接通过接口调用。
    • 抽象类可以包含静态方法和非静态方法,这些方法可以有实现。
  7. 设计目的

    • 接口主要用于定义一组规范或契约,它们是行为的集合。
    • 抽象类用于提供一个通用的模板,它可能包含一些通用的实现,同时定义一些必须由子类实现的方法。

示例

// 接口
interface Flyable {
    void fly();
}

// 抽象类
abstract class Animal {
    abstract void eat();

    void sleep() {
        System.out.println("Animal sleeps");
    }
}

// 实现接口
class Bird implements Flyable {
    public void fly() {
        System.out.println("Bird is flying");
    }
}

// 继承抽象类
class Dog extends Animal {
    public void eat() {
        System.out.println("Dog is eating");
    }
}

public class Main {
    public static void main(String[] args) {
        Flyable bird = new Bird();
        bird.fly(); // 通过接口引用调用方法

        Animal dog = new Dog();
        dog.eat(); // 通过抽象类引用调用方法
        dog.sleep(); // 调用抽象类中的具体方法
    }
}

在这个例子中,Flyable是一个接口,Animal是一个抽象类。Bird类实现了Flyable接口,而Dog类继承自Animal抽象类。接口和抽象类都用于定义规范和行为,但它们的使用方式和设计目的有所不同。

8. JAVA集合类的使用

Java集合类是Java标准库(Java Collections Framework,JCF)的一部分,提供了一组用于存储和处理对象集合的接口和类。集合类可以用于存储、检索、更新和操作数据。Java集合类分为几个主要类别,包括列表(List)、集合(Set)、映射(Map)和队列(Queue)。

8.1. 列表(List)

列表是有序的集合,允许重复的元素。主要的列表接口包括:

  • List<E>:有序的集合,可以包含重复的元素。
  • ArrayList<E>:基于动态数组实现的列表,提供快速随机访问。
  • LinkedList<E>:基于双向链表实现的列表,提供快速的插入和删除操作。

8.2. 集合(Set)

集合是无序的集合,不允许重复的元素。主要的集合接口包括:

  • Set<E>:无序的集合,不允许重复的元素。
  • HashSet<E>:基于散列实现的集合,提供快速的查找和插入操作。
  • LinkedHashSet<E>:类似于HashSet,但维护元素的插入顺序。
  • TreeSet<E>:基于红黑树实现的集合,元素按自然顺序或指定顺序排序。ASCII表顺序。

8.3. 映射(Map)

映射是键值对的集合,键是唯一的。主要的映射接口包括:

  • Map<K,V>:键值对的集合,键是唯一的,健值类型要一致,值的类型也要一致。
  • HashMap<K,V>:基于散列实现的映射,提供快速的查找和插入操作。
  • LinkedHashMap<K,V>:类似于HashMap,但维护键值对的插入顺序。
  • TreeMap<K,V>:基于红黑树实现的映射,键按自然顺序或指定顺序排序。

8.4. 队列(Queue)

队列是遵循先进先出(FIFO)原则的集合。主要的队列接口包括:

  • Queue<E>:先进先出的集合。
  • LinkedList<E>:可以用作队列的链表实现。
  • PriorityQueue<E>:基于优先级堆实现的队列,元素按优先级排序。

8.5. 其他集合类

  • Collection<E>ListSet的父接口,提供一些通用的操作。
  • Iterator<E>:用于遍历集合中的元素。
  • ListIterator<E>Iterator的子接口,提供双向遍历和修改列表的能力。
  • Comparable<E>Comparator<E>:用于定义对象的自然顺序和自定义排序。

示例

import java.util.*;

public class CollectionExample {
    public static void main(String[] args) {
        // 创建列表
        List<String> list = new ArrayList<>();
        list.add("Apple");
        list.add("Banana");
        System.out.println(list);

        // 创建集合
        Set<String> set = new HashSet<>();
        set.add("Apple");
        set.add("Banana");
        System.out.println(set);

        // 创建映射
        Map<String, Integer> map = new HashMap<>();
        map.put("Apple", 1);
        map.put("Banana", 2);
        System.out.println(map);

        // 创建队列
        Queue<String> queue = new LinkedList<>();
        queue.add("Apple");
        queue.add("Banana");
        System.out.println(queue);
    }
}

(1)如果涉及到堆栈、队列等操作,应该考虑用List,对于需要快速插入,删除元素,应该使用LinkedList,如果需要快速随机访问元素,应该使用ArrayList
(2)哈希表的操作,作为key的对象要正确复写equals和hashCode方法
(3)尽量返回接口而非实际的类型,如返回List而非ArrayList,这样如果将来要将ArrayList换成LinkedList时,客户端代码不用改变。
(4)List可以有类似数组的下标操作,且允许有相同的元素存在;Map是以键值对(KeyValue)的形式存在,不能存在相同的键。
(5)ArrayList类
ArrayList实现了可变大小的数组,长度随着元素的增加而变化,且可以存在重复的元

(6)HashMap类:允许null,即nullkey,null value。且存在的形式是key-value形式,不允许有key重复。

8.6. 迭代器(Iterator)

迭代器是Java集合框架中的一种设计模式,用于遍历集合中的元素。迭代器提供了一种统一的方式来访问集合中的每个元素,而不需要了解集合的内部结构。迭代器模式的主要优点是它支持对集合的迭代操作,而不需要暴露集合的内部结构。在Java中,迭代器通过java.util.Iterator接口实现,该接口定义了三个方法:

  1. boolean hasNext():返回true如果迭代器还有更多的元素,否则返回false
  2. E next():返回迭代器的下一个元素。
  3. void remove():从集合中移除迭代器的最后一个返回的元素。

迭代器通常与Collection接口一起使用,Collection接口的iterator()方法返回一个迭代器对象。以下是使用迭代器遍历集合的示例:

import java.util.ArrayList;
import java.util.Iterator;

public class IteratorExample {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("Apple");
        list.add("Banana");
        list.add("Cherry");

        // 获取迭代器
        Iterator<String> iterator = list.iterator();

        // 遍历集合
        while (iterator.hasNext()) {
            String fruit = iterator.next();
            System.out.println(fruit);
        }
    }
}

9 JAVA包、内部类和匿名类

9.1.包(Package)

包是一种组织类和接口的方式,用于将功能相关的类和接口分组在一起。包的主要目的是解决命名冲突问题,提高代码的可读性和可维护性,以及控制访问级别,java包通常反域名将类放置到包中,为了隐藏内部代码还可以将代码达成JAR包提供给消费者

9.2. 内部类:

在一个类的内部存在另外一个类就被成为内部类内部类的优点和缺点:
缺点:破坏了程序的结构
优点:方便的访问外部类中的私有属性
注意:此时内部类是无法直接访问的,如果想访问,需要使用static关键字

内部类(Inner Class)是定义在另一个类内部的类。在Java中,内部类提供了一种将相关类组合在一起的方式,同时保持了封装性和作用域的控制。内部类可以访问其外部类的所有成员,包括私有成员。

  1. 成员内部类(Static Inner Class):定义在另一个类内部的静态类。它不能访问外部类的实例成员(因为静态成员属于类,不属于实例)。

    public class OuterClass {
        public static class InnerClass {
            // 可以访问外部类的静态成员
        }
    }
    
  2. 非静态内部类(Non-static Inner Class):定义在另一个类内部的非静态类。它可以访问外部类的所有成员,包括私有成员。

    public class OuterClass {
        private int outerVar = 10;
    
        public class InnerClass {
            public void display() {
                System.out.println(outerVar); // 访问外部类的私有成员
            }
        }
    }
    
  3. 匿名内部类(Anonymous Inner Class):没有名称的内部类,通常用于创建短暂的对象。它们经常用在需要实现接口或继承类的场合。

    public class OuterClass {
        public void method() {
            // 匿名内部类实现接口
            MyInterface myObj = new MyInterface() {
                public void display() {
                    System.out.println("Anonymous Inner Class");
                }
            };
        }
    }
    

10 数组

在Java中,数组是一种用于存储固定大小的相同类型元素的集合。数组可以是一维的,也可以是多维的(如二维数组、三维数组等)。数组在内存中是连续存储的,这使得数组的访问非常快速,但也限制了它们的灵活性,因为它们的大小在创建后不能改变。

一维数组

一维数组是最简单的数组形式,它存储了一系列的相同类型的元素。以下是创建和使用一维数组的示例:

// 创建一个整型数组
int[] numbers = new int[5]; // 创建一个长度为5的整型数组

// 初始化数组
numbers[0] = 10;
numbers[1] = 20;
numbers[2] = 30;
numbers[3] = 40;
numbers[4] = 50;

// 遍历数组
for (int i = 0; i < numbers.length; i++) {
    System.out.println(numbers[i]);
}

多维数组

多维数组可以看作是数组的数组。二维数组常用于表示矩阵或表格。以下是创建和使用二维数组的示例:

// 创建一个二维整型数组
int[][] matrix = new int[3][4]; // 创建一个3行4列的二维整型数组

// 初始化数组
matrix[0][0] = 1;
matrix[0][1] = 2;
matrix[1][0] = 3;
matrix[1][1] = 4;
// ... 初始化其他元素

// 遍历二维数组
for (int i = 0; i < matrix.length; i++) {
    for (int j = 0; j < matrix[i].length; j++) {
        System.out.print(matrix[i][j] + " ");
    }
    System.out.println();
}

数组的特性

  • 固定大小:数组一旦创建,其大小就不能改变。
  • 同质性:数组中的所有元素必须是相同类型的。
  • 连续存储:数组元素在内存中是连续存储的,这使得数组的访问速度非常快。
  • 索引:数组通过索引访问元素,索引从0开始。

数组的局限性

  • 大小固定:数组的大小在创建时确定,之后不能改变。
  • 单一类型:数组只能存储一种类型的元素。
  • 内存浪费:如果数组的容量大于实际需要,可能会造成内存浪费。

11 字符串

在Java中,String类是java.lang包中的一个非常常用的类,用于表示和处理字符串。字符串在Java中是不可变的(immutable),这意味着一旦创建了一个字符串对象,它的内容就不能被改变。

String str = new String("Hello, World!"); // 使用String构造函数
String str2 = "Hello, World!"; // 使用字符串字面量

字符串的特性

  1. 不可变性:字符串一旦创建,其内容就不能被改变。任何修改字符串的操作都会创建一个新的字符串对象。
  2. 字符串池:Java维护一个字符串池,用于存储字符串字面量和通过String.intern()方法显式加入的字符串。这有助于节省内存,因为相同的字符串字面量在程序中只存储一份。

字符串的方法

String类提供了丰富的方法来操作字符串,包括:

  • 连接和拼接concat(String str), +操作符
  • 查找和比较charAt(int index), compareTo(String anotherString), equals(Object anObject), equalsIgnoreCase(String anotherString)
  • 搜索和匹配indexOf(int ch), indexOf(String str), contains(CharSequence s)
  • 替换和删除replace(char oldChar, char newChar), replace(CharSequence target, CharSequence replacement)
  • 分割和连接split(String regex), join(CharSequence delimiter, CharSequence... elements)
  • 大小写转换toLowerCase(), toUpperCase()
  • 修剪空白trim()

示例

public class StringExample {
    public static void main(String[] args) {
        String greeting = "Hello";
        String punctuation = "!";
        String message = greeting.concat(punctuation); // "Hello!"

        System.out.println(message.equalsIgnoreCase("hello!")); // true
        System.out.println(message.indexOf('o')); // 4

        String upperCase = message.toUpperCase(); // "HELLO!"
        System.out.println(upperCase);

        String trimmed = message.trim(); // "Hello!"
        System.out.println(trimmed);
    }
}

12.文件处理 Apache Commons IO

Apache Commons IO 是 Apache 软件基金会的一个库,提供了许多用于简化 Java IO 操作的工具和实用程序。它补充了 Java 标准库中的 IO 类,提供了更高级的文件操作功能,使得文件和流的处理更加容易和直观。

主要功能

  1. 文件过滤器:提供了各种文件过滤器,用于在文件操作中筛选文件和目录。

  2. 文件比较:提供了文件比较的工具,可以比较文件的内容或最后修改时间等。

  3. 文件复制和移动:提供了文件复制和移动的工具,支持缓冲和流控制。

  4. 文件删除:提供了递归删除目录和文件的工具。

  5. 临时文件管理:提供了创建和管理临时文件和目录的工具。

  6. 流操作:提供了各种流操作的工具,如复制流内容、转换流等。

  7. 字符编码转换:提供了字符编码转换的工具。

  8. 文件下载和上传:提供了文件下载和上传的工具。

使用示例

以下是一些使用 Apache Commons IO 的示例:

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class ApacheIOExample {
    public static void main(String[] args) {
        try {
            // 文件复制
            File sourceFile = new File("source.txt");
            File destFile = new File("dest.txt");
            FileUtils.copyFile(sourceFile, destFile);

            // 文件内容读取
            InputStream inputStream = new FileInputStream(sourceFile);
            String content = IOUtils.toString(inputStream, "UTF-8");
            IOUtils.closeQuietly(inputStream);
            System.out.println(content);

            // 文件内容写入
            OutputStream outputStream = new FileOutputStream(destFile);
            IOUtils.write("Hello, World!", outputStream, "UTF-8");
            IOUtils.closeQuietly(outputStream);

            // 递归删除目录
            File directoryToDelete = new File("directory");
            FileUtils.deleteDirectory(directoryToDelete);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  • Apache Commons IO 不是 Java 标准库的一部分,因此需要单独添加到项目的依赖中。
  • Apache Commons IO 提供了许多便利的方法,但在性能敏感的应用中,直接使用 Java 标准库可能更优。
  • Apache Commons IO 的一些方法可能会抛出 IOException,因此需要适当处理异常。

Apache Commons IO 是一个非常有用的库,它简化了许多常见的 IO 操作,使得开发者可以更专注于业务逻辑而不是底层的 IO 细节。通过使用 Apache Commons IO,可以提高开发效率和代码的可读性。

13. JAVA异常类的使用

13.1. 什么是异常?

程序出错分为两部分:编译时出错和运行时出错。编译时出错是编译器在编译源码时发生的错误;运行时出错,则是编译通过,在运行是出现的错误。这种情况叫异常。例:如数组越界,除数为0,文件找不到等等。
在Java中,异常可以分为两大类:检查型异常(Checked Exception)和非检查型异常(Unchecked Exception)。这两类异常在处理方式和使用上有所不同。

检查型异常(Checked Exception)
检查型异常是必须在编译时处理的异常,这意味着如果一个方法可能抛出检查型异常,那么这个方法必须使用throws关键字声明这个异常,或者在方法内部捕获这个异常。检查型异常通常是外部因素引起的问题,如文件未找到、网络连接失败等。

常见的检查型异常包括:

  • IOException:输入/输出异常,如文件读写错误。
  • SQLException:数据库访问异常。
  • ClassNotFoundException:类找不到异常。

非检查型异常(Unchecked Exception)
非检查型异常是编译器不强制处理的异常,包括运行时异常(RuntimeException)和错误(Error)。这些异常通常是程序内部逻辑错误引起的,如空指针异常、数组越界等。

运行时异常(RuntimeException)
运行时异常是程序运行时可能发生的错误,通常是由于程序逻辑错误或不当使用API引起的。常见的运行时异常包括:

  • NullPointerException:尝试使用空对象时抛出。
  • ArrayIndexOutOfBoundsException:数组索引越界时抛出。
  • IllegalArgumentException:传递非法或不适当的参数时抛出。
  • IllegalStateException:方法调用与对象状态不兼容时抛出。

错误(Error)
错误是严重的程序问题,通常是不可恢复的,如系统崩溃、虚拟机错误等。常见的错误包括:

  • OutOfMemoryError:内存不足时抛出。
  • StackOverflowError:递归调用太深导致栈溢出时抛出。
  • VirtualMachineError:虚拟机错误,如NoClassDefFoundErrorClassCastException等。
public class ExceptionDemo {
    public static void main(String[] args) {
        try {
            // 可能抛出检查型异常的代码
            FileReader reader = new FileReader("nonexistent.txt");
        } catch (FileNotFoundException e) {
            System.out.println("File not found: " + e.getMessage());
        }

        try {
            // 可能抛出运行时异常的代码
            int[] numbers = new int[5];
            System.out.println(numbers[10]);
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("Array index out of bounds: " + e.getMessage());
        }
    }
}

java异常类的层次
在这里插入图片描述
处理异常
在这里插入图片描述

13.2. 创建自定义异常

自定义异常类只要继承基类,同时实现方法

在Java中,自定义异常是指开发者根据特定应用需求创建的异常类。自定义异常使得错误处理更加具体化,有助于清晰地表达程序中可能遇到的各种错误情况。创建自定义异常通常是通过继承Exception类或其子类来实现的。

创建自定义异常类通常涉及以下步骤:

  1. 确定异常类型:根据错误的性质,决定是继承Exception(检查型异常)还是RuntimeException(运行时异常)。

  2. 定义异常类:创建一个新的类,继承自ExceptionRuntimeException,并添加必要的构造函数和其他方法。

  3. 实现构造函数:提供至少一个构造函数,通常包括一个无参构造函数和一个接受字符串消息的构造函数。也可以提供其他构造函数,如接受Throwable对象的构造函数,用于链式异常。

  4. 添加方法:根据需要添加额外的方法,这些方法可以提供关于异常的更多信息或执行特定的错误处理逻辑。

以下是一个自定义异常的示例,用于处理用户输入无效的情况:

// 自定义异常类
public class InvalidUserInputException extends Exception {
    // 无参构造函数
    public InvalidUserInputException() {
        super();
    }

    // 接受错误消息的构造函数
    public InvalidUserInputException(String message) {
        super(message);
    }

    // 接受错误消息和原因的构造函数
    public InvalidUserInputException(String message, Throwable cause) {
        super(message, cause);
    }
}

// 使用自定义异常
public class UserInputValidator {
    public void validateInput(String input) throws InvalidUserInputException {
        if (input == null || input.isEmpty()) {
            throw new InvalidUserInputException("Input cannot be null or empty.");
        }
        // 其他验证逻辑...
    }
}

public class Main {
    public static void main(String[] args) {
        UserInputValidator validator = new UserInputValidator();
        try {
            validator.validateInput(null);
        } catch (InvalidUserInputException e) {
            System.out.println("Error: " + e.getMessage());
        }
    }
}


# 14. FILE 文件管理
在Java中,`java.io.File`类是用于表示文件和目录的抽象表示,它提供了丰富的方法来处理文件和目录。`File`类不是用于流式输入输出的,而是用于文件和目录的属性访问、文件系统导航、文件的创建、删除等操作。
```java
import java.io.File;

public class FileExample {
    public static void main(String[] args) {
        // 创建File对象
        File file = new File("example.txt");

        // 检查文件是否存在
        if (file.exists()) {
            System.out.println("File exists.");
        } else {
            System.out.println("File does not exist.");
        }

        // 创建文件
        try {
            if (file.createNewFile()) {
                System.out.println("File created.");
            } else {
                System.out.println("File already exists.");
            }
        } catch (IOException e) {
            System.out.println("An error occurred.");
        }

        // 删除文件
        if (file.delete()) {
            System.out.println("File deleted.");
        } else {
            System.out.println("Failed to delete file.");
        }

        // 列出目录中的文件
        File directory = new File(".");
        File[] files = directory.listFiles();
        if (files != null) {
            for (File f : files) {
                System.out.println(f.getName());
            }
        }
    }
}

http://www.kler.cn/news/366707.html

相关文章:

  • linux softirq tasklet 软中断实现
  • redis集群配置
  • 2024Flutter面试题
  • 2.4_Docker与防火墙
  • 二、Hadoop 基础知识综述
  • 【计算机网络 - 基础问题】每日 3 题(五十七)
  • leetcode动态规划(十七)-组合总和IV
  • Python小游戏9——天天酷跑
  • Laravel使用 Swagger
  • 超详细Redis安装配置【包成功的】
  • 系统架构设计师 软件架构的定义与生命周期
  • week08 zookeeper多种安装与pandas数据变换操作-new
  • UE5学习笔记26-添加游戏热身时间,比赛时间,重新开始比赛
  • 【jvm】所有的线程都共享堆吗
  • 【mysql进阶】4-7. 通用表空间
  • 理解 python 类
  • 某ai gpt的bug
  • go的web服务器框架
  • 南京林业大学生态学博士在1区top期刊揭示人工林发育促进土壤团聚体的形成与稳定:对土壤碳氮固存的启示
  • 多端项目开发全流程详解 - 从需求分析到多端部署
  • C语言 | Leetcode C语言题解之第508题斐波那契数
  • 24. Lammps命令学习-系统定义部分总结
  • MySQL-日志
  • qt QWidget详解
  • LeetCode刷题日记之贪心算法(五)
  • Vim 编辑器从入门到入土