Java基础入门之——内部类、异常、泛型

这篇文章详细介绍了Java编程中的内部类,包括成员内部类、局部内部类和匿名内部类的使用。同时,讲解了异常处理的基本概念,如Error和Exception的区别,以及如何使用try-catch进行异常捕获。此外,还深入探讨了泛型的应用,包括泛型类、泛型方法、泛型接口和类型通配符的使用场景。
摘要由CSDN通过智能技术生成

内部类

内部类可以访问外部类的变量(包括private),外部类要访问内部类方法,要创建内部类对象。

成员内部类(类中方法体外)

一个类想要调用成员内部类:Outer.Inner inner = new Outer().new Inner();
以上方法对与public内部类可行,但内部类一般用于隐藏在类里面,所以一般是private,一般写一个方法来被调用。

class Outer {
    public class Inner {
        public void show(){
            System.out.println("内部类");
        }
    }
    //对外提供调用的方法
    public void show() {
        Inner in = new Inner();
        in.show();
    }
}

局部内部类(方法体内)

也是间接调用方法,方法体中调用内部类。

class Outer {
    public void show() {
        class Inner {
            public void show(){
                System.out.println("内部类");
            }
        }
        
        Inner in = new Inner();
        in.show();
    }
}

匿名内部类(局部内部类的一种)

前提:存在一个类或接口,这里的类可以是具体类也可以是抽象类。
本质:是继承了该类或实现了该接口的子类对象。

interface inter {
    void show();
}
class Outer {
    public void show() {
        new inter(){
            @Override
            public void show() {
                System.out.println("匿名内部类");
            }
        }.show();
        
        Inter inter = new inter(){
            @Override
            public void show() {
                System.out.println("匿名内部类");
            }
        };
        inter.show();
    }
}

异常

在这里插入图片描述
Error:严重问题,不需要处理,代码无法处理。
Exception:异常类,他表示程序本身可以处理的问题。
RuntimeException:在编译时不检查,出现问题后,我们需要回过头修改代码。
非RuntimeException:在编译时检查。

  • Throwable(所有异常的祖宗)
    它有三个成员方法
    在这里插入图片描述
    public static void main(String[] args){
        try {
            throw new ArrayIndexOutOfBoundsException("message");
        } catch (ArrayIndexOutOfBoundsException e) {
            //message
            System.out.println(e.getMessage());
            //java.lang.ArrayIndexOutOfBoundsException: message
            System.out.println(e.toString());
            /* java.lang.ArrayIndexOutOfBoundsException: message
            	     at Main.main(Main.java:4)    */
            e.printStackTrace();
        }
    }

Throwable有多个构造方法,有参构造messgae传入给成员变量detailMessage赋值,存储异常信息。
大多使用e.printStackTrace();打印完整。

  • try-catch
        int[] array = {1, 2, 3};
        try {
            System.out.println(array[3]);//new ArrayIndexOutOfBoundsException
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("数组越界");
            e.printStackTrace();
        }
  • throws
    只是抛出异常,并没有对异常进行处理,还是需要try-catch处理。
public static void main(String[] args) throws ArrayIndexOutOfBoundsException{
        int[] array = {1, 2, 3};
        System.out.println(array[3]);//new ArrayIndexOutOfBoundsException
        System.out.println("数组越界");//异常没被处理,不会输出
    }
  • 自定义异常
public class Main {
    public static void main(String[] args){
        Checker c = new Checker();
/*
        OutOfRangeException: 分数>100
        at Checker.check(Main.java:13)
        at Main.main(Main.java:5)
*/
        try {
            c.check(200);
        } catch (OutOfRangeException e) {
            e.printStackTrace();
        }
    }
}
class Checker {
    public void check(int x) throws OutOfRangeException{
        if (x > 100) throw new  OutOfRangeException("分数>100");
        else System.out.println("分数<=100");
    }
}
class OutOfRangeException extends Exception {
    public OutOfRangeException() {
    }

    public OutOfRangeException(String message) {
        super(message);
    }
}

泛型

它的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。一提到参数, 最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。那么参数化类型怎么理解呢?
顾名思义,就是将类型由原来的具体的类型参数化,然后在使用/调用时传入具体的类型。这种参数类型可以用在类、方法和接口中,分别被称为泛型类、泛型方法、泛型接口。
泛型定义格式:

  • <类型>: 指定一种类型的格式。这里的类型可以看成是形参
  • <类型1,类型2…>: 指定多种类型的格式,多种类型之间用逗号隔开。这里的类型可以看成是形参

将来具体调用时候给定的类型可以看成是实参, 并且实参的类型只能是引用数据类型。

泛型类

格式:public class Generic<T>() {},这里的T可以是任意标识,常见的如我们E、K、V等形式的参数常用于表示泛型。

public class Main {
    public static void main(String[] args){
        Generic<Integer> g1 = new Generic<Integer>(1);
        Generic<String> g2 = new Generic<String>("java");
        System.out.println(g1.t);//1
        System.out.println(g2.t);//String
    }
}
public class Generic <T>{
    T t;
    public Generic(T t) {
        this.t = t;
    }
    public Generic() {
    }
    public T getT() {
        return t;
    }
    public void setT(T t) {
        this.t = t;
    }
}

泛型方法

public class Main {
    public static void main(String[] args){
        Generic<Integer> g1 = new Generic<Integer>();
        Generic<String> g2 = new Generic<String>();
        g1.show(1);
        g2.show("java");
    }
}
public class Generic <T>{
    public void show(T x) {
        System.out.println(x);
    }
}

用泛型类,这样定义对象每次都要给定类型,有没有更好的方法?泛型方法就可以解决。
格式:public <T> void show(T t) {}

public class Main {
    public static void main(String[] args){
        Generic g1 = new Generic();
        g1.show(1);
        g1.show("java");
    }
}
public class Generic{
    public <T> void show(T x) {
        System.out.println(x);
    }
}

泛型接口

格式:public interface Generic <T> {}

public class Main {
    public static void main(String[] args){
        Generic<Integer> g1 = new GenericImpl<Integer>();
        g1.show(1);
        Generic<String> g2 = new GenericImpl<String>();
        g2.show("java");
    }
}
public interface Generic <T>{
     void show(T x);
}
public class GenericImpl <T> implements Generic<T>{
    @Override
    public void show(T x) {
        System.out.println(x);
    }
}

类型通配符

为了表示各种泛型List的父类,可以使用类型通配符

  • 类型通配符: <?>
  • List<?>: 表示元素类型末知的List,它的元素可以匹配任何的类型
  • 这种带通配符的List仅表示它是各种泛型List的父类,不能把元素添加到其中

如果说我们不希望List<?>是任何泛型List的父类,只希望它代表某一类泛型List的父类 ,可以使用类型通配符的上限

  • 类型通配符上限: <? extends 类型>
  • List<? extends Number>:它表示的类型是Number或者其子类型

除了可以指定类型通配符的上限,我们也可以指定类型通配符的下限

  • 类型通配符 下限: <? super 类型>
  • List<? super Number>:它表示的类型是Number或者其父类型
public class Main {
	public static void main(String[] args) {
		List<?> list1 = new ArrayList<Object>();
		List<?> list2 = new ArrayList<Number>();
		List<?> list3 = new ArrayList<Integer>();
		System.out.println("-----------");

		// 类型通配符上限
//		List<? extends Number> list4 = new ArrayList<Object>();
		List<? extends Number> list5 = new ArrayList<Number>();
		List<? extends Number> list6 = new ArrayList<Integer>();

		// 通配符下限
		List<? super Number> list7 = new ArrayList<Object>();
//		List<? super Number> list8 = new ArrayList<Integer>();
		List<? super Number> list9 = new ArrayList<Number>();

	}
}

要求该泛型的类型,只能是实参类型,或实参类型的子类类型。

public class Main {
	public static void main(String[] args) {
		Generic01<Number> num = new Generic01();
		num.setNum(100);
		showBox(num);

		Generic01<Integer> num2 = new Generic01();
		num2.setNum(200);
		showBox(num2);
	}

	// 通配符上限Number
	public static void showBox(Generic01<? extends Number> g1) {
		Number num01 = g1.getNum();
		System.out.println(num01);
	}
}
public class Generic01<T> {
	private T num;

	public T getNum() {
		return num;
	}

	public void setNum(T num) {
		this.num = num;
	}

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值