1998年12月8日,第二代Java平台的企业版J2EE发布。
1999年6月,Sun公司发布了第二代Java平台(简称为Java2)的3个版本:
J2ME(Java2 Micro Edition,Java2平台的微型版):应用于移动、无线及有限资源的环境
J2SE(Java 2 Standard Edition,Java 2平台的标准版):应用于桌面环境
J2EE(Java 2Enterprise Edition,Java 2平台的企业版):应用于基于Java的应用服务器
Java 2平台的发布,是Java发展过程中最重要的一个里程碑,标志着Java的应用开始普及
在JDK1.5之前一个集合可以放任何类型的对象,相应地从集合里面拿对象的时候我们也不得不对他们进行强制的类型转换。引入了泛型之后,它允许指定集合里元素的类型,这样在编译阶段就会对对象进行类型检查。
for(元素的数据类型 变量名 : 数组或集合){
}
自动装箱:基本类型自动转为包装类
自动拆箱:包装类自动转为基本类型
修饰符 enum 枚举名{
变量名1,变量名2;
}
可变参数使程序员可以声明一个接受可变数目参数的方法。
注意,可变参数必须是函数生命中的最后一个参数。
同一个类中,调用静态变量,方法,可以省略类名
主要用于操作JavaBean中的属性,通过getXxx/setXxx。一般的做法是通过类Introspector来获取某个对象的BeanInfo信息,然后通过BeanInfo来获取属性的描述器(PropertyDescriptor),通过这个属性描述器就可以获取某个属性对应的getter/setter方法,然后我们就可以通过反射机制来调用这些方法。
实际返回类型可以是要求的返回类型的一个子类型
一种利用拉模式解析(pull-parsing)XML文档的API。类似于SAX,也基于事件驱动模型。之所以将StAX加入到JAXP家族,是因为JDK6中的JAXB2和JAX-WS 2.0中都会用StAX
使用Compiler API,动态编译Java源文件,如JSP编译引擎就是动态的,所以修改后无需重启服务器
轻量级Http Server API,据此可以构建自己的嵌入式HttpServer,它支持Http和Https协议
提供了Console类用以开发控制台程序,位于java.io包中。据此可方便与Windows下的cmd或Linux下的Terminal等交互
如:ruby,groovy,,javascript
Common Annotations,原是J2EE 5.0规范的一部分,现在把它的一部分放到了J2SE 6.0中
Desktop和SystemTray,其中前者用来通过系统默认程序来执行一个操作,如使用默认浏览器浏览指定的URL,用默认邮件客户端给指定的邮箱发邮件,用默认应用程序打开或编辑文件(比如,用记事本打开以txt为后缀名的文件),用系统默认的打印机打印文档等。后者可以用来在系统托盘区创建一个托盘程序
//泛型声明后边的<>可以省略不写泛型
ArrayList<String> list = new ArrayList<>();
从JDK1.7开始,可以用二进制来表示整数(byte,short,int和long)。使用二进制字面量的好处是,可以是代码更容易被理解。语法非常简单,只要在二进制数值前面加 0b或者0B。
用下划线连接整数提升其可读性,自身无含义,不可用在数字的起始和末尾。
Java编码语言对给数值型的字面值加下划线有严格的规定。如上所述,你只能在数字之间用下划线。你不能用把一个数字用下划线开头,或者已下划线结尾。这里有一些其它的不能在数值型字面值上用下划线的地方:
float pi1 = 3_.1415F; // 无效的; 不能在小数点之前有下划线
float pi2 = 3._1415F; // 无效的; 不能在小数点之后有下划线
long socialSecurityNumber1=999_99_9999_L;//无效的,不能在L下标之前加下划线
int a1 = _52; // 这是一个下划线开头的标识符,不是个数字
int a2 = 5_2; // 有效
int a3 = 52_; // 无效的,不能以下划线结尾
int a4 = 5_______2; // 有效的
int a5 = 0_x52; // 无效,不能在0x之间有下划线
int a6 = 0x_52; // 无效的,不能在数字开头有下划线
int a7 = 0x5_2; // 有效的 (16进制数字)
int a8 = 0x52_; // 无效的,不能以下划线结尾
int a9 = 0_52; // 有效的(8进制数)
int a10 = 05_2; // 有效的(8进制数)
int a11 = 052_; // 无效的,不能以下划线结尾
在Java 7中,catch代码块得到了升级,用以在单个catch块中处理多个异常。如果你要捕获多个异常并且它们包含相似的代码,使用这一特性将会减少代码重复度。下面用一个例子来理解。
catch(IOException | SQLException | Exception ex){
logger.error(ex);
throw new MyException(ex.getMessage());
}
try-with-resources语句是一个声明一个或多个资源的try语句。一个资源作为一个对象,必须在程序结束之后关闭。try-with-resources语句确保在语句的最后每个资源都被关闭,任何实现了Java.lang.AutoCloseable和java.io.Closeable的对象都可以使用try-with-resource来实现异常处理和关闭资源。
JDK1.7之前
/**
* JDK1.7之前我们必须在finally块中手动关闭资源,否则会导致资源的泄露
* @author Liao
*
*/
public class PreJDK7 {
public static String readFirstLingFromFile(String path) throws IOException {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(path));
return br.readLine();
} catch (IOException e) {
e.printStackTrace();
} finally {//必须在这里关闭资源
if (br != null)
br.close();
}
return null;
}
}
JDK1.7之后
/**
* JDK1.7之后就可以使用try-with-resources,不需要 我们在finally块中手动关闭资源
*
* @author Liao
*/
public class AboveJDK7 {
static String readFirstLineFromFile(String path) throws IOException {
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
}
修饰符 default 返回值类型 方法名(参数列表){
方法体;
}
@Test
public void test2() {
// 如果用Lambda表达式,一定要写明泛型
List<String> list = Arrays.asList("peter","anna","make");
// ①.老版本的Java中是这样排列字符串的
Collections.sort(list, new Comparator<String>() {
@Override
public int compare(String a, String b) {
return a.compareTo(b);
}
});
// ②.Java 8提供了更简洁的语法,lambda表达式:
/*
Collections.sort(list ,(String a,String b) -> {
return a.compareTo(b);
});
// ③.还可以写得更短
Collections.sort(list, (String a, String b) -> a.compareTo(b));
// ④.还可以这么写
Collections.sort(list, String::compareTo);
System.out.println(Collections.singletonList(list)); //[[anna, make, peter]]
}
什么是λ表达式
λ表达式本质上是一个匿名方法。让我们来看下面这个例子:
public int add(int x, int y) {
return x + y;
}
转成λ表达式后是这个样子:
(int x, int y) -> x + y;
参数类型也可以省略,Java编译器会根据上下文推断出来:
(x, y) -> x + y; //返回两数之和
或者
(x, y) -> { return x + y; } //显式指明返回值
可见λ表达式有三部分组成:
1、参数列表
2、箭头(->)
3、以及一个表达式或语句块。
通常与Lambda表达式联合使用,可以直接引用已有Java类或对象的方法。
一般有四种不同的方法引用:
1、构造器引用。语法是Class::new,或者更一般的Class< T >::new,要求构造器方法是没有参数;
2、静态方法引用。语法是Class::static_method,要求接受一个Class类型的参数;
3、特定类的任意对象方法引用。它的语法是Class::method。要求方法是没有参数的;
4、特定对象的方法引用,它的语法是instance::method。要求方法接受一个参数,与3不同的地方在于,3是在列表元素上分别调用方法,而4是在某个对象上调用方法,将列表元素作为参数传入。
在Java 5中使用注解有一个限制,即相同的注解在同一位置只能声明一次。Java 8引入重复注解,这样相同的注解在同一地方也可以声明多次。重复注解机制本身需要用@Repeatable注解。Java 8在编译器层做了优化,相同注解会以集合的方式保存,因此底层的原理并没有变化。
Java 8扩展了注解的上下文,几乎可以为任何东西添加注解,包括局部变量、泛型类、父类与接口的实现,连方法的异常也能添加注解。
Java 8引入Optional类来防止空指针异常,Optional类最先是由Google的Guava项目引入的。Optional类实际上是个容器:它可以保存类型T的值,或者保存null。使用Optional类我们就不用显式进行空指针检查了。
Stream API是把真正的函数式编程风格引入到Java中。其实简单来说可以把Stream理解为MapReduce,当然Google的MapReduce的灵感也是来自函数式编程。她其实是一连串支持连续、并行聚集操作的元素。从语法上看,也很像linux的管道、或者链式编程,代码写起来简洁明了,非常酷帅。
Java 8新的Date-Time API (JSR 310)受Joda-Time的影响,提供了新的java.time包,可以用来替代 java.util.Date和java.util.Calendar。一般会用到Clock、LocaleDate、LocalTime、LocaleDateTime、ZonedDateTime、Duration这些类,对于时间日期的改进还是非常不错的。
Nashorn允许在JVM上开发运行JavaScript应用,允许Java与JavaScript相互调用。
在Java 8中,Base64编码成为了Java类库的标准。Base64类同时还提供了对URL、MIME友好的编码器与解码器。