Java关键知识点之高级特性

汇总:Android小白成长之路_知识体系汇总【持续更新中…】

异常

  • java中,异常对象都是派生于Throwable类的一个实例,下一层分为两个分支:ErrorException

    • Error:Java运行时系统的内部错误和资源耗尽错误,应用程序不应该抛出这种类型的对象
    • Exception:又分为两个分支,一个分支派生于RuntimeException,另一个分支包含其他异常,由程序错误导致的异常属于RuntimeException,而程序本身没问题,但由于下像I/O错误这类问题导致的异常属于其他异常
      • RuntimeException:错误的类型转换,数组访问越界,访问null指针,应该修改避免,而不是捕获处理
      • 其他异常:试图在文件尾部后面读取数据,试图打开一个不存在的文件,试图根据给定的字符串查找Class对象,但这个类并不存在。这类异常必须捕获或者抛出异常,不处理的话编译器将报错
  • 使用try/catch语句块捕获异常,如果在try语句中的任何代码抛出了一个在catch子句中说明的异常类,那么程序将跳过try语句块其余代码,并开始执行catch子句中的处理代码,如果catch子句中没有声明这个异常类型,则会立刻退出这个方法

  • finally子句:不管是否有异常被捕获,这个子句的代码都会被执行,如果代码抛出了异常,但异常没被catch子句捕获,那么try的代码执行中断,直接开始执行finally里的代码,可以只有tryfinally语句,而没有catch子句

  • 有一种不错的捕获异常的写法:

    try{
    	try{
    		...
    	}finally{
    		//释放资源
    	}
    }catch(Excepyion e){
    	...
    }
    

    内层的try语句块只有一个职责,就是确保资源被释放,而外层的try语句块也只有一个职责,就是确保捕获出现的错误,这样写可以连finally里出现的异常都一起捕获了

  • 当利用return语句从try语句块中退出,在方法返回前,finally子句的内容将被执行。如果finally子句中也有一个return语句,这个返回值将会覆盖原始的返回值

泛型

  • 泛型程序设计意味着编写的代码可以被很多不同类型的对象所重用

  • 泛型类:

    public class Pair<T>
    {
    	private T first;
    	private T second;
    	public Pair(){first = null; second = null}
    	public Pair(T first,T second){this.first = first;this.second = second;}
    	public T getFirst(){return first;}
    	public T getSecond(){return second;}
    }
    

    Pair类引入一个类型变量T,用尖括号<>括起来,并放在类名后,泛型类可以有多个类型变量,例如:

    public class Pair<T, U>{}
    
  • 泛型方法:

    public static <T> T getMiddle(T... a){
    	return a[a.length / 2];
    }
    

    类型变量放在修饰符的后面,返回类型的前面,当调用泛型方法时,在方法名前的尖括号里放入具体的类型:

    String middle = <String>getMiddle("a","b","c");
    
  • 类型变量的限定:

    public static <T extends Comparable> T min(T[] a)...
    

    上面的形式将泛型T限制为实现了Comparable接口的类,如果传入的类型不满足这个规则,将编译报错。一个类型变量或通配符可以有多个限定,如:

    T extends Comparable & Serializable
    

    限定类型用&隔开

  • 类型擦除:无论何时定义一个泛型类型,都自动提供了一个相应的原始类型,原始类型的名字就是删去类型类型参数后的泛型类型名,擦除类型变量,并替换为限定类型(没有限定的变量默认为Object),例如Pair<T>的原始类型如下:

    public class Pair
    {
    	private Object first;
    	private Object second;
    	public Pair(){first = null; second = null}
    	public Pair(Object first,Object second){this.first = first;this.second = second;}
    	public Object getFirst(){return first;}
    	public Object getSecond(){return second;}
    }
    

    如果有多个限定的类型,则原始类型用第一个限定的类型变量来替换,如果要切换限定,编译器在必要时要向要切换的限定插入强制类型转换,因此为了提高效率,应该将没有方法的接口放在边界列表的末尾

  • 泛型的约束和局限性:

    • 不能使用基本类型实例化类型参数,例如没有Pair<double>,只有Pair<Double>,其原因是类型擦除,擦除后原始类型是Object,而Object不能存储double值(基本类型的值)

    • 运行时类型查询只适用于原始类型,不适用于泛型,也就是下面的查询是错误的:

      if(a instanceof Pair<T>) ...
      
    • 不能创建参数化类型的数组,例如以下的写法是错误的:

      Pair<String>[] table = new Pair<String>[10];
      

      因为类型擦除后,table的类型是Pair[]。可以将其转换为Object[],数组会记住它的元素类型,如果存储其他类型的元素,就会抛出一个ArrayStoreException异常,因此不允许创建参数化类型的数组。不过可以声明类型为Pair<String>[]的变量,但不能用new Pair<String>[10];初始化

    • 不能实例化类型变量,例如下面的写法是错误的:

      public Pair(){first = new T(); second = new T();}
      
    • 不能构造泛型数组,例如下面的写法是错误的:

      public static <T extends Comparable> T[] minmax(T[] a){T[] mm = new T[2];}
      

      类型擦除会使这个方法永远构造Comparable[2]数组

    • 泛型类的静态上下文中类型变量无效,不能在静态域或方法中引用类型变量,例如:

      public class Singleton<T>
      {
      	private static T singleInstance;	//error
      	public static T getSingleInstance()	//error
      	{
      		if(singleInstance == null) return new SingleInstance();
      		return singleInstance;
      	}
      }
      

      类型擦除后,只剩下Singleton类,将只包含一个singleInstance域,通俗来说,也就是静态域或方法优先于类等的实例化,因此并不知道真正传递的参数类型是什么,所以无法使用

    • 不能抛出或捕获泛型类的实例

    • 可以消除对受查异常的检测,java异常处理有一个基本原则是必须为所有受查异常提供一个处理器,不过可以利用泛型擦除消除这个限制

通配符类型

  • 通配符类型中,允许类型参数变化,例如:

    Pair<? extends Employee>
    

    表示任何泛型Pair类型,它的类型参数是Employee的子类

  • 通配符限定与类型变量限定类似,但有一个附加的能力,即可以指定一个超类型限定,例如:

    ? super Manager
    

    这个通配符限制为Manager的所有超类型

  • 带有超类型限定的通配符可以向泛型对象写入,带有子类限定的通配符可以从泛型对象读取

  • 无限定通配符,例如Pair<?>Pair<?>和Pair的本质不同在于:可以用任意Object对象调用原始Pair类的setObject方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Nbin_Newby

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值