01_01_java基础#_jdk发布与新特性

jdk(Java Development Kit)发布及新增特性

Java 1.0

  • 1996.01.23
  • Sun公司发布了Java的第一个开发工具包

Java 1.1

  • 1997.02.19
  • JavaOne会议召开,创当时全球同类会议规模之最

Java1.2

  • 1998.12.08
  • Java拆分成:J2SE(标准版)、J2EE(企业版)、J2ME(微型版)

Java1.3

  • 2000.05.08

Java1.4

  • 2004.02.06

Java5.0

  • 2004.09.30
  • 版本号从1.4变为5.0
  • 平台更名为JavaSE、JavaEE、JavaME
  • 5.0之前需要自定义枚举类型–>5.0之后Java开始支持使用enum关键字来快速定义枚举类型
//java5.0之前
class Season{

    private final String seasonName;

    private final String seasonDesc;

    private Season(String seasonName,String seasonDesc){
        this.seasonName = seasonName;
        this.seasonDesc = seasonDesc;
    }

    public String getSeasonName() {
        return seasonName;
    }

    public String getSeasonDesc() {
        return seasonDesc;
    }

    public static final Season SPRING = new Season("春天","春暖花开");
    public static final Season SUMMER = new Season("夏天","夏日炎炎");
    public static final Season AUTUMN = new Season("秋天","秋高气爽");
    public static final Season WINTER = new Season("冬天","白雪皑皑");

    @Override
    public String toString() {
        return "Season{" +
                "seasonName='" + seasonName + '\'' +
                ", seasonDesc='" + seasonDesc + '\'' +
                '}';
    }
}
enum Season1{
    //开头
    SPRING("春天","春暖花开"),
    SUMMER("夏天","夏日炎炎"),
    AUTUMN("秋天","秋高气爽"),
    WINTER("冬天","白雪皑皑");
    private final String seasonName;
    private final String seasonDesc;

    private Season1(String seasonName,String seasonDesc){
        this.seasonName = seasonName;
        this.seasonDesc = seasonDesc;
    }

    public String getSeason1Name() {
        return seasonName;
    }

    public String getSeason1Desc() {
        return seasonDesc;
    }



    @Override
    public String toString() {
        return "Season1{" +
                "seasonName='" + seasonName + '\'' +
                ", seasonDesc='" + seasonDesc + '\'' +
                '}';
    }
}
  • 以”@注解名”在代码中添加注解
  • 线程状态改变
  • 创建线程的新的方法
    • 实现Callable接口
    • 线程池创建线程
    /*
     * 创建多线程的方式三:实现Callable (jdk5.0新增的)
     */
    //1.创建一个实现Callable的实现类
    class NumThread implements Callable {
        //2.实现call方法,将此线程需要执行的操作声明在call()中
        @Override
        public Object call() throws Exception {
            int sum = 0;
            for (int i = 1; i <= 100; i++) {
                if (i % 2 == 0) {
                    System.out.println(i);
                    sum += i;
                }
                Thread.sleep(1000);
            }
            return sum;
        }
    }
    
    
    public class CallableTest {
        public static void main(String[] args) {
            //3.创建Callable接口实现类的对象
            NumThread numThread = new NumThread();
    
            //4.将此Callable接口实现类的对象作为传递到FutureTask构造器中,创建FutureTask的对象
            FutureTask futureTask = new FutureTask(numThread);
    
            //5.将FutureTask的对象作为参数传递到Thread类的构造器中,创建Thread对象,并调用start()
            Thread t1 = new Thread(futureTask);
            t1.start();
    
            System.out.println("main()线程");
    
            try {
                //6.获取Callable中call方法的返回值
                //get()返回值即为FutureTask构造器参数Callable实现类重写的call()的返回值。
                Object sum = futureTask.get();
                System.out.println("总和为:" + sum);
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    }
    
  • StringBuilder:可变的字符串;线程不安全,效率高
  • foreach循环

Java6.0

  • 2006.12.11
  • 2009.04.20Oracle宣布收购SUN公司

Java7.0

  • 2011.07.02
  • 字符串常量池从方法区
  • 中存放到堆空间中
  • 开始可以在switch中匹配使用
  • 泛型类型推断
  • 异常处理资源自动关闭

    try(资源对象的声明和初始化){
    业务逻辑代码,可能会产生异常
    }catch(异常类型1 e){
    处理异常代码
    }catch(异常类型2 e){
    处理异常代码
    }

    //举例1
    @Test
    public void test02() {
        try (
            FileWriter fw = new FileWriter("d:/1.txt");
            BufferedWriter bw = new BufferedWriter(fw);
        ) {
            bw.write("hello");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    //举例2
    @Test
    public void test03() {
        //从d:/1.txt(utf-8)文件中,读取内容,写到项目根目录下1.txt(gbk)文件中
        try (
            FileInputStream fis = new FileInputStream("d:/1.txt");
            InputStreamReader isr = new InputStreamReader(fis, "utf-8");
            BufferedReader br = new BufferedReader(isr);
    
            FileOutputStream fos = new FileOutputStream("1.txt");
            OutputStreamWriter osw = new OutputStreamWriter(fos, "gbk");
            BufferedWriter bw = new BufferedWriter(osw);
        ) {
            String str;
            while ((str = br.readLine()) != null) {
                bw.write(str);
                bw.newLine();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    

Java8.0(LTS)

  • 2014.03.18

  • 此版本是继Java5.0以来变化最大的版本。长期支持

  • 接口内部结构的说明:

    可以声明:
    属性:必须使用public static final修饰
    方法:jdk8之前:声明抽象方法,修饰为public abstract
    jdk8:声明静态方法:只能接口自己调用,实现类不能调用
    默认方法:可以被实现类重写
    不可以声明:构造器、代码块等

    • 把方法区改名为元空间
  • 日期api的更改

    JDK 1.0中包含了一个java.util.Date类,但是它的大多数方法已经在JDK 1.1引入Calendar类之后被弃用了。而Calendar并不比Date好多少。它们面临的问题是:

    • 可变性:像日期和时间这样的类应该是不可变的。
    • 偏移性:Date中的年份是从1900开始的,而月份都从0开始。
    • 格式化:格式化只对Date有用,Calendar则不行。
    • 此外,它们也不是线程安全的;不能处理闰秒等。
      闰秒,是指为保持协调世界时接近于世界时时刻,由国际计量局统一规定在年底或年中(也可能在季末)对协调世界时增加或减少1秒的调整。由于地球自转的不均匀性和长期变慢性(主要由潮汐摩擦引起的),会使世界时(民用时)和原子时之间相差超过到±0.9秒时,就把协调世界时向前拨1秒(负闰秒,最后一分钟为59秒)或向后拨1秒(正闰秒,最后一分钟为61秒); 闰秒一般加在公历年末或公历六月末。
      目前,全球已经进行了27次闰秒,均为正闰秒。
      总结:对日期和时间的操作一直是Java程序员最痛苦的地方之一
      第三次引入的API是成功的,并且Java 8中引入的java.time API 已经纠正了过去的缺陷,将来很长一段时间内它都会为我们服务。
      Java 8 以一个新的开始为 Java 创建优秀的 API。新的日期时间API包含:
    • java.time – 包含值对象的基础包
    • java.time.chrono – 提供对不同的日历系统的访问。
    • java.time.format – 格式化和解析时间和日期
    • java.time.temporal – 包括底层框架和扩展特性
    • java.time.zone – 包含时区支持的类
      说明:新的 java.time 中包含了所有关于时钟(Clock),本地日期(LocalDate)、本地时间(LocalTime)、本地日期时间(LocalDateTime)、时区(ZonedDateTime)和持续时间(Duration)的类。
      尽管有68个新的公开类型,但是大多数开发者只会用到基础包和format包,大概占总数的三分之一。
  • Lambda表达式

    Lambda 表达式:在Java 8 语言中引入的一种新的语法元素和操作符。这个操作符为 “->” , 该操作符被称为 Lambda 操作符箭头操作符。它将 Lambda 分为两个部分:
    左侧:指定了 Lambda 表达式需要的参数列表
    右侧:指定了 Lambda 体,是抽象方法的实现逻辑,也即 Lambda 表达式要执行的功能.

    语法格式一: 无参,无返回值

    @Test
    public void test1(){
        //未使用Lambda表达式
        Runnable r1 = new Runnable() {
            @Override
            public void run() {
                System.out.println("我爱北京天安门");
            }
        };
    
        r1.run();
    
        System.out.println("***********************");
    
        //使用Lambda表达式
        Runnable r2 = () -> {
            System.out.println("我爱北京故宫");
        };
    
        r2.run();
    }
    

    语法格式二: Lambda 需要一个参数,但是没有返回值。

    @Test
    public void test2(){
        //未使用Lambda表达式
        Consumer<String> con = new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        };
        con.accept("谎言和誓言的区别是什么?");
    
        System.out.println("*******************");
    
        //使用Lambda表达式
        Consumer<String> con1 = (String s) -> {
            System.out.println(s);
        };
        con1.accept("一个是听得人当真了,一个是说的人当真了");
    
    }
    

    语法格式三: 数据类型可以省略,因为可由编译器推断得出,称为“类型推断”

    @Test
    public void test3(){
        //语法格式三使用前
        Consumer<String> con1 = (String s) -> {
            System.out.println(s);
        };
        con1.accept("一个是听得人当真了,一个是说的人当真了");
    
        System.out.println("*******************");
        //语法格式三使用后
        Consumer<String> con2 = (s) -> {
            System.out.println(s);
        };
        con2.accept("一个是听得人当真了,一个是说的人当真了");
    
    }
    

    语法格式四: Lambda 若只需要一个参数时,参数的小括号可以省略

    @Test
    public void test4(){
        //语法格式四使用前
        Consumer<String> con1 = (s) -> {
            System.out.println(s);
        };
        con1.accept("一个是听得人当真了,一个是说的人当真了");
    
        System.out.println("*******************");
        //语法格式四使用后
        Consumer<String> con2 = s -> {
            System.out.println(s);
        };
        con2.accept("一个是听得人当真了,一个是说的人当真了");
    }
    

    语法格式五: Lambda 需要两个或以上的参数,多条执行语句,并且可以有返回值

    @Test
    public void test5(){
        //语法格式五使用前
        Comparator<Integer> com1 = new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                System.out.println(o1);
                System.out.println(o2);
                return o1.compareTo(o2);
            }
        };
    
        System.out.println(com1.compare(12,21));
        System.out.println("*****************************");
        //语法格式五使用后
        Comparator<Integer> com2 = (o1,o2) -> {
            System.out.println(o1);
            System.out.println(o2);
            return o1.compareTo(o2);
        };
    
        System.out.println(com2.compare(12,6));
    }
    

    语法格式六: 当 Lambda 体只有一条语句时,return 与大括号若有,都可以省略

    @Test
    public void test6(){
        //语法格式六使用前
        Comparator<Integer> com1 = (o1,o2) -> {
            return o1.compareTo(o2);
        };
    
        System.out.println(com1.compare(12,6));
    
        System.out.println("*****************************");
        //语法格式六使用后
        Comparator<Integer> com2 = (o1,o2) -> o1.compareTo(o2);
    
        System.out.println(com2.compare(12,21));
    
    }
    
    @Test
    public void test7(){
        //语法格式六使用前
        Consumer<String> con1 = s -> {
            System.out.println(s);
        };
        con1.accept("一个是听得人当真了,一个是说的人当真了");
    
        System.out.println("*****************************");
        //语法格式六使用后
        Consumer<String> con2 = s -> System.out.println(s);
    
        con2.accept("一个是听得人当真了,一个是说的人当真了");
    
    }
    
  • 函数式接口

  • 方法引用与构造器引用

  • 强大的streamAPI

Java9.0

  • 2017.09.22
  • 此版本开始每半年更新一次
  • 不再支持windows 32位系统

接口中可以声明私有方法
提出公共内容以供该接口默认方法调用

  • 存储字符串的容器变为byte[];
  • jShell
  • try的前面可以定义流对象,try后面的()中可以直接引用流对象的名称。在try代码执行完毕后,流对象也可以释放掉,也不用写finally了。

    A a = new A();
    B b = new B();
    try(a;b){
    可能产生的异常代码
    }catch(异常类名 变量名){
    异常处理的逻辑
    }

    @Test
    public void test04() {
        InputStreamReader reader = new InputStreamReader(System.in);
        OutputStreamWriter writer = new OutputStreamWriter(System.out);
        try (reader; writer) {
            //reader是final的,不可再被赋值
            //   reader = null;
    
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    

Java10.0

  • 2018.03.21
  • 局部类型推断

Java11.0(LTS)

  • 2018.09.25
  • JDK安装包取消独立JRE安装包

Java12.0

  • 2019.03.19

Java13.0

  • 文本块

    使用"""作为文本块的开始符和结束符,在其中就可以放置多行的字符串,不需要进行任何转义。因此,文本块将提高Java程序的可读性和可写性。

    原有写法:

     String text1 = "The Sound of silence\n" +
                    "Hello darkness, my old friend\n" +
                    "I've come to talk with you again\n" +
                    "Because a vision softly creeping\n" +
                    "Left its seeds while I was sleeping\n" +
                    "And the vision that was planted in my brain\n" +
                    "Still remains\n" +
                    "Within the sound of silence";
    
    System.out.println(text1);
    

    现在写法:

    String text2 = """
                    The Sound of silence
                    Hello darkness, my old friend
                    I've come to talk with you again
                    Because a vision softly creeping
                    Left its seeds while I was sleeping
                    And the vision that was planted in my brain
                    Still remains
                    Within the sound of silence
                    """;
    System.out.println(text2);
    

Java14.0

  • instanceof的模式匹配

    14以前:

    if(obj instanceof String){
        String str = (String)obj; //需要强转
        .. str.contains(..)..
    }else{
        ...
    }
    

    14以后

    if(obj instanceof String str){
        .. str.contains(..)..
    }else{
        ...
    }
    
  • Record
    //旧写法
    class Point {
        private final int x;
        private final int y;
    
        Point(int x, int y) {
            this.x = x;
            this.y = y;
        }
    
        int x() {
            return x;
        }
    
        int y() {
            return y;
        }
    
        public boolean equals(Object o) {
            if (!(o instanceof Point)) return false;
            Point other = (Point) o;
            return other.x == x && other.y == y;
        }
    
        public int hashCode() {
            return Objects.hash(x, y);
        }
    
        @Override
        public String toString() {
            return "Point{" +
                    "x=" + x +
                    ", y=" + y +
                    '}';
        }
    }
    
    //新写法
    record Point(int x, int y) { }
    

Java15.0

  • 密封类

    在 Java 中如果想让一个类不能被继承和修改,这时我们应该使用 final 关键字对类进行修饰。不过这种要么可以继承,要么不能继承的机制不够灵活,有些时候我们可能想让某个类可以被某些类型继承,但是又不能随意继承,是做不到的。Java 15 尝试解决这个问题,引入了 sealed 类,被 sealed 修饰的类可以指定子类。这样这个类就只能被指定的类继承。
    通过密封的类和接口来限制超类的使用,密封的类和接口限制其它可能继承或实现它们的其它类或接口。
    具体使用:
    使用修饰符sealed,可以将一个类声明为密封类。密封的类使用保留关键字permits列出可以直接扩展(即extends)它的类。
    sealed 修饰的类的机制具有传递性,它的子类必须使用指定的关键字进行修饰,且只能是 finalsealednon-sealed 三者之一。

    public abstract sealed class Shape permits Circle, Rectangle, Square {...}
    
    public final class Circle extends Shape {...} //final表示Circle不能再被继承了
    
    public sealed class Rectangle extends Shape permits TransparentRectangle, FilledRectangle {...}
    
    public final class TransparentRectangle extends Rectangle {...}
    
    public final class FilledRectangle extends Rectangle {...}
    
    public non-sealed class Square extends Shape {...} //non-sealed表示可以允许任何类继承
    

Java16.0

Java17.0(LTS)

  • 2021.09
  • 版本号也称21.9
  • switch模式匹配
  • Java 12将会对switch声明语句进行扩展,使用case L ->来替代以前的break;,省去了 break 语句,避免了因少写 break 而出错。
  • 同时将多个 case 合并到一行,显得简洁、清晰,也更加优雅的表达逻辑分支。
  • 为了保持兼容性,case 条件语句中依然可以使用字符 : ,但是同一个 switch 结构里不能混用 -> : ,否则编译错误。

Java18.0

Java19.0

Java20.0

Java21.0

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

过于执

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

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

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

打赏作者

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

抵扣说明:

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

余额充值