Java基础知识拾遗(二)
Lambda表达式
lambda表达式本质上就是一个匿名方法。但是这个方法不是独立执行的,而是构成了一个函数式接口定义的抽象方法的实现,该函数式接口定义了它的目标类型。
只有在定义了lambda表达式的目标类型的上下文中,才能使用该表达式。当把一个lambda表达式赋给一个函数式接口引用时,就创建了这样的上下文。
interface MyNumber {
double getValue();
}
MyNumber myNum ;
myNum = () -> 12;
lambda表达式会导致产生一个匿名类。lambda表达式也常被称为闭包。
函数式接口是仅包含一个抽象方法的接口。这个方法知名了接口的目标用途。函数式接口定义了lambda表示的目标类型。特别注意,lambda表达式只能用于其目标
类型已被指定的上下文中。另外,函数式接口有时候 被称为SAM类型,意思是但抽象方法。
函数式接口可以指定Object定义的任何公有方法。Object的公有方法被视为函数式接口的隐士成员,因为函数式接口的实例会默认自动实现他们。
lambda体只包含单个表达式,这种类型的lambda体被称为表达式体,或者表达式lambda。Java支持另外一种类型lambda表达式,其中操作符右侧的代码可以由一个
代码块构成。其中包含多条语句,这种类型被称为块体,或者块lambda。在块lambda中必须显示使用return语句来返回值。必须这么做,因为块lambda体代表的不是单独
一个表达式。当lambda表达式中出现return语句时,只是从lambda体返回,而不会导致包围lambda体的方法返回。
泛型函数式接口,lambda表达式自身不能指定类型参数,因此lambda表达式不能是泛型。但与lambda表达式关联的函数式接口可以是泛型。
interface SomeFunc<T> {
T func(T t);
}
SomeFunc<String> reverse = (str) -> {
String result = "";
//...
}
SomeFunc<Interge> factoral = (n) -> {
//...
}
作为参数传递lambda表达式,为了将lambda表达式作为参数传递,接受lambda表达式的参数类型必须是与该lambda表达式兼容的函数式接口类型。
lambda表达式与异常,lambda表达式可以抛出异常。如果抛出检查异常,该异常就必须与函数式接口的抽象方法的throws子句中列出的异常兼容。
预定义的函数式接口, 很多时候不需要自己定义函数式接口,JDK8中包含了新报java.util.function,其中提供了一些预定以的函数式接口。
接口 用途
UinaryOperator<T> 对类型为T的对象应用一元运算,结果是T。包含方法apply()
BinaryOperator<T> 对类型为T的两个对象应用操作,结果是T。包含方法apply()
Consumer<T> 对类型为T的对象应用操作,包含方法accept()
Supplier<T> 返回类型为T的对象。包含方法get()
Function<T, R> 对类型为T的对象应用操作,结果是类型R的对象。包含方法apply()
Predicate<T> 确定类型为T的对象是否满足某种约束,返回布尔值。包含方法test()
String
valueOf,方法将数据从内部格式转换成人类可以阅读的形式。valueOf()是静态方法,String针对所有Java内置类型对该方法进行重载,从而可以将每种
类型正确地转换成字符串。传递给valueOf()方法的所有对象都将返回调用对象的toString()方法的结果。
Number
抽象类Number定义了一个超累,用于封装数值类型byte、short、int、long、float及double的类派生自这个超类。
Float和Double都提供了isInfinite()和isNaN(),如果值在数量上为无穷大或者无穷小,那么isInfiniter()返回true,如果测试值不是数字,那么isNaN()返回true.
对Unicode代码点的附加支持
Java对Character进行了较大的扩充。从JDK1.5开始,Character开始支持32为的Unicode字符。在过去所有Unicode字符都使用16位保存,这是char类型的
大小,因为这些值的范围都是从0到FFFF。但是Unicode字符集已经进行扩展,需要比16为更多的存储空间,现在,字符的范围可以从0到10FFFF。
代码点,是指0到10FFFF;数值大于FFFF的字符被称为补充字符,基本多语言平面字符是指0到FFFF之间的那些字符。
对Unicode字符集的扩展给java带来了一些基本问题。因为附加字符的值大于char能够保存的值,所以需要一些处理补充字符的手段。Java通过两种方法解决
这个问题。首先,java使用两个char表示一个附加字符,第一个char称为高代理,第二个char称为低代理。java提供了一些新方法,用于在代码点和补充字符之间
进行转换,比如codePointAt()。
Java重载了Character类中以前存在的一些方法。这些方法的重载形式使用int型而不是char型数据。因为对于作为单个值保存任何字符而言,int是足够大的,
所以int用于保存任何字符。
Void类
Void类只有域变量TYPE,用来保存对void类型的class对象的引用。不用创建Void类型的实例。
Runtime类
Runtime类封装了运行时环境。可以调用静态的Runtime.getRuntime()方法来获得对当前Runtime对象的引用。一旦获得对当前Runtime对象的引用,就可以
调用一些放来来控制JVM的状态和行为。
clone方法和Cloneable接口
clone()方法产生调用对象的副本。只有实现了Clone接口的类才可以被复制。Cloneable接口没有定义成员,用于指示可以按位复制对象。当进行复制时不
会调用被复制对象的构造函数。复制品是原始对象的精确副本。在Object类中,clone()方法被声明为protected。这意味着clone()方法只能在实现了Cloneable接口
的类定义的方法中调用,或者只能在类中显示地进行重写,进而成为公有的。
ThreadGroup类
线程组为管理一组线程提供了一种便利的方式,可以将一组线程作为一个单元进行管理。对于希望挂起或者恢复大量相关线程的情况,线程组特别有用。
StackTraceElement类
StackTraceElement类描述单个的堆栈帧,堆栈帧是当异常发生时对战踪迹的单个元素。每个堆栈帧表示一个执行点,包含类名、方法名、文件名、以及源代码
行号这类信息。Throwable类的getStackTrace()方法返回一个StackTraceElement数组。
Appendable接口
实现了Appendable接口的类的对象,可以追加字符或字符序列。
Readable接口
Readable接口指示对象可以用作字符的源,该接口定义了方法read().
AutoCloseable接口
AutoCloseable接口对带资源的try语句提供了支持。这种try语句所实现的功能,有时被称为自动资源管理。当资源不再需要时,带try的语句会自动释放资源。只有
实现了AutoColseable接口的类对象,才能被用于带资源的try语句。