目录

自定义异常类

简单说一下泛型


自定义异常类

系统提供的异常类不足

需求:模拟feiq上线如果没插网线,就抛出一个没插网线的异常,如果,插上网线,正在显示好友列表。

利用ip来判断一下有没有网线这里模拟成字符串。

自定义一个类来继承Exception类:

自做:完成这个ip异常处理

利用父类的Exception来处理异常对象

我们还可以不捕获,继续抛出去,比如main调用,我们就抛给虚拟机

1.演示一个自定义异常,完了把它抛给虚拟机

class Excep

{

public static void main(String[] args) throws NoIpException

{  

String ip=null;

/*try{

feiQ(ip);

}catch(NoIpException e)

{

e.printStackTrace();//打印异常栈信息

}*/

feiQ(ip);

}

public static void feiQ(String ip)

{

if(ip==null)

{

throw new NoIpException("没有插网线");

}

System.out.print("正常显示");

}

}

//继承一下老大

class NoIpException extends Exception

{

public NoIpException(String str)

{

super(str);//传递错误信息

}

需求:吃法,10元,没带够钱的异常,如果带够了,就可以吃饭了。

自己来做这样一个异常。

//定义一个没带钱的异常
//把这个异常用在一个方法上
class NoMoneyException extends Exception{
    //传入异常信息
    public NoMoneyException(String message){
        super(message);
    }
}

public static void eat(int money) throws NoMoneyException{
        if(money < 10){
            //函数内部抛出一个异常,函数声明上面我得抛啊
            throw new NoMoneyException("我钱不够,我特么吃不了饭");
        }else{
            System.out.println("我现在可以吃饭了");
        }
    }

下面来说一下:如果方法内部抛出一个运行时异常,运行时异常在方法上可声明就声明,想处理就处理

Exception:1.运行时异常(通过程序员良好的习惯去避免)2.编译时异常

什么是运行时异常?

除了上面运行时异常,就是编译时异常。

那么多,怎么记?

不用记。

直接用文档查就好了。

               

上面就是抛出了一个线程中断异常,为什么必须抛出一个线程中断异常呢?而这个异常又是一个编译异常

我们看看wait()本身这个函数

很明显它是抛出了一个线程中断时异常。

我们知道调用一个抛出了异常的方法,我们必须进行处理,要么捕获,要么进行抛出,特别又是编译异常的函数。

下面我们来说另外一个问题:

一个读取,一个删除,能不能成功。明显不能。

说明资源文件一旦使用完毕,一定要释放,不然其他程序将无法操作此文件。这种事情是程序来做的。

就算是读到一半出了异常,也要把文件释放出去,别人才可以来对文件进行操作

finally 块;

finally块的 使用前提是必须要存在try块才能使用。

finally块的代码在任何情况下都会执行的,除了jvm退出的情况。

finally非常适合做资源释放的工作,这样子可以保证资源文件在任何情况下都 会被释放。

第一种: 比较适用于有异常要处理,但是没有资源要释放的。

 try{

可能发生异常的代码;

}catch(捕获的异常类型 变量名){

处理异常的代码;

}

第二种:比较适用于既有异常要处理又要释放资源的代码。

try{

可能发生异常的代码;

}catch(捕获的异常类型 变量名){

处理异常的代码;

}finally{

释放资源的代码;

}

第三种: 比较适用于内部抛出的是运行时异常,并且有资源要被释放。

   try{

可能发生异常的代码;

}finally{

释放资源的代码;

}

上面就退出了虚拟机,不会执行那个finally块中的代码

下面我们简单来写一个读取文件异常的代码处理:

简单说一下泛型

1。接口泛型

            接口泛型是在实现接口的时候指定的类型
            当然在实现接口的时候也可以不传递具体的类型,他默认就为Object类型
            很可能就是你在用的时候,要手动变为相应的数据类型

        这里实现接口的类,不传入具体类型有一个条件就是:该类也是带有泛型参数的类

         

2.泛型的上下限
   

public class UpperBoundedExample {
    public static <T extends Number> double sum(List<T> list) {
        double sum = 0;
        for (T element : list) {
            sum += element.doubleValue();
        }
        return sum;
    }

    public static void main(String[] args) {
        List<Integer> integers = Arrays.asList(1, 2, 3);
        List<Double> doubles = Arrays.asList(1.5, 2.5, 3.5);

        System.out.println("Sum of integers: " + sum(integers));
        System.out.println("Sum of doubles: " + sum(doubles));
    }
}

 在这个例子中,<T extends Number> 表示泛型 T 必须是 Number 类或其子类。这使得 sum 方法可以接受 List<Integer>List<Double>

public class LowerBoundedExample {
    public static void addNumbers(List<? super Integer> list) {
        for (int i = 1; i <= 5; i++) {
            list.add(i);
        }
    }

    public static void main(String[] args) {
        List<Object> objectList = new ArrayList<>();
        addNumbers(objectList);

        System.out.println("Numbers added to the list: " + objectList);
    }
}

 在这个例子中,<? super Integer> 表示泛型的类型必须是 Integer 或者 Integer 的父类型。这使得 addNumbers 方法可以接受 List<Object> 或更泛化的类型。

泛型的几个引用规则

1.如果一个接口定义了泛型,普通类(没有泛型接口的类)去实现它的时候必须指明确定的类型
2.但是如果这个类也标明了相应的泛型,就可以不指定类型,后面new的时候在标出具体的类型就可以
    class Test2Demo1<K,V> implements Test2.Entry<K,V> {
3.不管是静态方法还是非静态方法,都是按照下面这种格式定义泛型
    //在泛型参数上指定上限
    public <T extends SomeType> void myMethod(T value) {
    // 方法体
    }
    //在方法参数上指定上限
    public <T> void myMethod(List<? extends SomeType> myList) {
    // 方法体
    }

    静态想要使用泛型,必须有占位符,也就是<>括起来。然后我们再来说一下返回的类型,参数类型,这两个位置的泛型可以使用泛型,也可以不使用泛型。具体由你自己来定义。
4.泛型中传入指定类型,这个指定类型也可以包含泛型
     public static <K extends Comparable<K>,V> Comparator<Entry<K,V>> comparingByKey()
     public interface Comparator<T>我们来看这个Comparator比较器本身就要传入一个泛型
     然后我们上面传入的是一个Entry接口实现类,这个实现类又包含了<K,V>泛型
5.在泛型方法中,可以独立于类上声明的新泛型参数
    public class Example<T> {
    private T value;

       // 类级别的泛型参数 T
    public Example(T value) {
        this.value = value;
    }

    // 泛型方法,定义了独立于类级别的泛型参数 U
    public <U> void printU(U u) {
        System.out.println(u);
    }

  6. 关于方法返回值强制转换&拼接多个接口的问题                                                                                   除非这个接口是一个声明式接口,没有任何的实现方法

对上面的返回来说Serializable是被Comparator显示声明实现的 ,并且没有没有任何抽象方法声明

另外说一点,在java中,如果一个接口有默认方法,它的实现类是可以去调用这个方法的。                           

8.泛型返回类型如果没有声明泛型,那么这个就是好一个原始类型。 

与局部变量返回无关

  • 这个方法的返回类型是原始类型 RBNode,所以当调用方使用 getNode() 方法时,返回的将是 RBNode(即原始类型),而不是 RBNode<K, V>。此时,泛型信息被擦除,KV 被视为 Object 类型。

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐