标签:简化 function 映射 内核 抽象方法 异常 推断 缓冲 声明
记录Java实用知识点,截止(包括)到Java8,只作概要的描述,不涉及到具体细节。
变量:
int、long的包装类支持无符号位操作,即其在内存中的位可以用来全部表示正数。
“_”可以用来分隔数值(整形、浮点数皆可),且可以用在多种数值系统里(二进制、十六进制等)。例:3.14_15F,0xCAFE_BABE。
如果一个常量(static final)是基本类型或字符串字面量,编译器会直接把常量替换成相应的值,对常量变更,则所有使用此常量的类需要重新编译。
对静态变量初始化时,可以使用静态初始化块,也可以在赋值表达式中直接引用静态方法。例:static int i = staticMethod(); 实例变量同理,不过要注意实例方法被子类覆盖问题(可以使用final方法)。
继承:
方法重载属于静态多分派(既考虑静态调用对象,又考虑方法参数),在编译时确定;方法重写属于动态单分派(只考虑实际调用对象),在运行时确定。
在源码中方法签名只由名称和参数确定,在字节码中方法签名还包括返回类型、异常等等。
方法重写的条件包括:子类有权限访问父类的方法,方法签名相同,权限、返回类型、抛出异常兼容。
实例中的静态方法可以被继承,但无法被覆盖,属于静态分派。接口中的静态方法无法被继承。
多继承时,类方法优先于接口默认方法;两个接口继承同一个接口中的方法,如果一个接口覆盖了此方法,则此接口优先。
泛型:
泛型允许将类型当作参数使用。Java泛型通过擦除实现,仅在编译期对泛型进行类型检查。
参数化类型指有类型参数的泛型,原生类型指不带泛型参数的泛型(非泛型类型不是原生类型)。
为了兼容性,参数化类型和原生类型可以相互转换,因此会破坏泛型的稳定性。例:List<String> sLi = new ArrayList<>();List rawLi = sLi;rawLi.add(1);
同一个泛型的不同参数化类型不能相互转换,但使用通配符、边界限定能改变此种行为。
在容器中,下界、无界通配符限定后除了null不能添加别的元素,上界通配符限定可以添加上界的子集元素。
可以使用辅助方法捕获通配符的类型信息,从而解除使用通配符的限制。如可以将List<?>的变量传给接受List<T>作为参数的方法,捕获通配符的类型。
内部类:
成员内部类通过外部类实例创建,Outer.Inner inner = out.new Inner(); 在内部类中可通过Outer.this(外部类类名.this)访问外部类同名实例变量。
在内部类(局部类、匿名类)中使用外部类的局部变量(或方法参数)时必须为final或等效于final(因为局部变量与对象生命周期不同),使用外部类实例变量不受此限制。
非静态内部类中不能有静态成员、静态代码块(常量除外)。
接口是固有静态的,不能在局部块中定义。
Lambda:
Lambda表达式使用功能性接口简化代码的编写,表现上比内部类更加简洁。
遇到方法重载时,Lambda表达式使用参数、方法返回类型等去推断目标类型,从而决定调用哪个方法。
Lambda表达式使用词法作用域,Lambda表达式本身不引入额外的作用域层次,也不继承接口(目标类型)中的变量。在Lambda表达式中使用外部局部变量时,该变量也必须为final或等效于final。
词法作用域范围由在代码中的位置决定,动态作用域范围由运行时环境决定,大多数编程语言使用词法作用域。
功能性接口(functional interface)指只包含一个抽象方法的接口,但接口中可以有多个默认方法或静态方法。
Java8预定义了很多功能性接口,如Predicate<T>用来判定某个条件、Consumer<T>用来执行某个行为、Function<T,R>接受T类型的操作并返回R类型的值(T映射到R)。
Stream用来对数组、容器等进行流式操作,Stream中的方法接受功能性接口类型作为参数并返回Stream,所以能进行链式调用。
注解:
注解是一种特定的接口,用来对程序进行描述。注解本身只是一种元数据,但可以通过程序对被注解的程序进行处理。
类型注解(type annotation)可以用在任何使用类型(Type)的地方,包括变量声明、构造实例(new 表达式)、转型、继承、异常抛出等。
类型注解可以用来增强Java的类型检查,避免程序中潜在错误,如可以使用@NonNull来避免NullPointerException。
可重复注解可以在一个目标上被多次使用。由于兼容性问题,可重复注解还需定义相应的容器注解才能使用(不知道注解里面为什么不能用泛型,不然容器注解就不需要重复定义)。
容器注解的目标(@Target)必须是可重复注解的目标的子集,否则不能通过编译。
异常:
方法执行出错时,抛出相应异常到方法调用栈帧,如果异常没有得到处理,则沿调用栈一直传递,直至线程终结。异常不能跨线程捕获。
受检异常指程序能够预期并应得到处理的异常,错误指程序外部不可预期的异常,运行时异常指程序内部由代码问题造成的异常,应该避免。错误和运行时异常为非受检异常。
异常总是被第一个匹配的catch块捕获,在一个catch块中能捕获多个异常,如catch(E1|E2 e),捕获多个异常时,异常参数为隐式final类型。
try、catch中如果有返回值,会先存储返回值(此处返回值不是变量本身,而是变量所指向的具体值或对象引用),执行完finally块再返回,如果finally有返回值则会覆盖try、catch中的返回值。finally抛出的异常会压制(suppress)try、catch中抛出的异常。
try-with-resources语句自动关闭(调用close方法)实现java.lang.AutoCloseable(java.io.Closeable为其子接口)的资源(resource),关闭顺序与声明顺序相反,try块中抛出的异常会压制try-with-resources中关闭资源时抛出的异常。catch、finally块在资源关闭后执行。
在异常对象上调用getSuppressed方法(Throwable中定义)可以获取被压制的异常。
方法中抛出的异常声明可以为调用其它方法时所抛出的异常类型的所有可能被抛出的具体子类异常集合。
传统I/O:
I/O(传统I/O,非NIO)需要在应用程序(用户态)和操作系统(内核态)之间切换。
缓冲通过减少程序与外部活动(磁盘、网络等)之间的切换次数,从而提高性能。
字符流是对字节流的封装,底层使用字节流进行I/O操作,在此基础上提供字符与字节之间的转换。
标签:简化 function 映射 内核 抽象方法 异常 推断 缓冲 声明
原文地址:http://www.cnblogs.com/changshanfeilong/p/7718720.html