深入Java7的一些新特性以及对脚本语言支持API的介绍

1.switch条件语句中可以加入字符串了,实现方法是利用了字符串的hashcode()值作业真正的值
2.增加了一种可以在字面量中使用的进制,二进制,通过在数字前面加“0b”或“0B”
3.在数字字面量中使用下划线来分隔数字方便阅读,不影响数值大小。基本原则是前后都是数字的才可以出现下划线
4.java7对异常做了两个改动:

  4.1.支持在一个catch子句中同时捕获多个异常,另外一个是在捕获并重新抛出异常时的异常类型更加精确。java7中Throwable类增加addSuppressed方法,当一个异常被抛出的时候,可能有其他异常因为该异常而被抑制住,从而无法正常抛出。这时可以通过addSuppressed方法把这些被抑制的方法记录下来,被抑制的异常会出现在抛出的异常的堆栈信息中,也可以通过getSuppressed方法来获取这些异常。这样做的好处是不会丢失任何异常,方便开发人员测试。


代码如下:

public class ReadFile(){
     public void read(String filename) throws IOException {
         FileInputStream input = null;
         IOException readException = null;
         try {
             input = new FileInputStream(filename);
         } catch (IOException ex) {
             readException = ex;
         } finally {
             if (input != null) {
                 try {
                     input.close();
                 } catch (IOException ex) {
                     if (readException != null) {
                         readException.addSuppressed(ex);
                     } else {
                         readException = ex;
                     }
                 }
             }
             if (readException != null) {
                 throw readException;
             }
         }
     }
 }

这种做法的关键在于把finally语句中产生的异常通过addSuppressed方法加到try语句产生的异常中。

java7改进了catch子句的语法,允许在其中指定多种异常,每个异常类型之间使用“|”来分隔。需要注意的是在catch子句中声明捕获的这些异常,不能出现重复的类型,也不允许其中的某个异常是另外一个异常参数的子类,否则会出现编译错误(从小到大写就没问题)。如果在catch子句中声明了多个异常,那么异常参数的具体类型是所有这些异常类型的最小上界。

  4.2使用try(申请资源){业务处理}来自动释放资源,能够被try语句所管理的资源需要满足一个条件,那就是其java类要实现java.lang.AutoCloseable接口,否则会出现编译错误。当需要释放资源的时候该接口的close方法会被自动调用。

5. 优化变长参数的方法调用:
j2se5.0中引入的一个新特性就是允许在方法声明中使用可变长度的参数。一个方法的最后一个形式参数可以被指定为代表任意多个相同类型的参数。在调用的时候,这些参数是以数组的形式来传递的。在方法体中也可以按照数组的方式来引用这些参数。

6. java7引入了一个新的注解@SafeVarargs.如果开发人员确信某个使用了可变长度参数的方法,在与泛型类一起使用进不会出现类似的情况,就可以用这个注解进行声明。@SafeVarargs注解只能用在参数长度可变的方法或构造方法上,且方法必须声明为static或final,否则会出现编译错误。一个方法使用@SafeVarargs注解的前提是,开发人员必须确保这个方法的实现中对泛型类型参数的处理不会引发类型安全问题。

7.java中在java虚拟机中支持一些脚本语言是通过脚本引擎。实际上脚本引擎管理器共支持三种查找引擎方式,分别通过名称,文件扩展名和MIME类型来完成。如


代码如下:

public void greet() throws ScriptException {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("JavaScript");
        if (engine == null) {
            throw new RuntimeException("找不到JavaScript语言执行引擎");
        }
        engine.eval("println('hello');");
    }

还可以通过getEngingByExtension("js")和getEngineByMimeType("text/javascript")来查找到。得到脚本引擎ScriptEngine的对象后,通过其eval方法可以执行一段代码,并返回这段代码的执行结果。

7.1 语言绑定:
脚本语言支持api的一个很大优势在于它规范了java语言与脚本语言之间的交互方式,使java语言编写的程序可以与脚本之间进行双向的方法调用和数据传递。数据传递是通过语言绑定对象来完成的。所谓的语言绑定对象就是一个简单的哈希表,用来存放和获取需要共享的数据。所有数据都对应这个哈希表中的一个条目,是简单的名值对。接口javax.script.Bingings定义了语言绑定对象的接口,它继承自java.util.Map接口。一个脚本引擎在执行过程中可能会使用多个语言绑定对象。不同语言绑定对象的作用域不同。在默认情况下,脚本引擎会提供多个语言绑定对象,用来存放在执行过程中产生的全局对象等。ScriptEnging类提供了put和get方法对脚本引擎中特定使用哉的默认语言绑定对象进行操作。程序可以直接使用这个默认的语言绑定对象,也可以使用自己的语言绑定对象。在脚本执行过程中,可以将语言绑定对象看成是一个额外的变量映射表。在解析变量值的时候,语言绑定对象中的名称也会被考虑在内。脚本 执行过程中产生的全局变量等内容,会出现在语言绑定对象中。通过这种方式,就完成了Java与脚本语言之间的双向数据传递。
如通过ScriptEngine的put方法向脚本引擎默认的语言绑定对象中添加了一个名为“name”的字符串,接着在脚本中直接根据名称来引用这个对象。同样,在脚本中创建的全局变量“message”也可以通过ScriptEnging的get方法来获取。这样就实现了Java程序与脚本之间的双向数据传递。数据传递过程中的类型转换是由脚本引擎来完成的,转换规则取决于具体的语言的语法


代码如下:

public void useDefaultBinging() throws ScriptException {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("JavaScript");
        // ScriptEngine engine = getJavaScriptEnging();
        engine.put("name", "World");
        engine.eval("var message = 'hello,'+name;");
        engine.eval("println(message)");
        Object obj = engine.get("message");
        System.out.println(obj);
    }

在大多数情况下,使用ScriptEnging的put和get方法就足够了。如果仅使用put和get方法,语言绑定对象本身对于开发人员来说是透明的。在某些情况下,需要使用程序自己的语言绑定对象,比如语言绑定对象中包含了程序自己独有的数据。如果希望使用自己的语言绑定对象,可以调用脚本引擎的creatBingings方法或创建一个javax.script.SimpleBingings对象,并传递给脚本引擎的eval方法如:


代码如下:

public void useCustomBinding()throws ScriptException
    {
    ScriptEngine engine = getJavaScriptEngine();
    Bindings bindings = new SimpleBindings();
    bindings.put("hobby","play games");
    engine.eval("println('I like'+hobby);",bindings);
    }

通过eval方法传递的语言绑定对象,仅在当前eval调用中生效,并不会改变引擎默认的语言绑定对象

7.2 脚本执行上下文
与脚本引擎执行相关的另外一个重要接口是javax.script.ScriptContext,其中包含脚本引擎执行过程中的相关上下文信息,可以与JavaEE中servlet规范中的javax.servlet.ServletContext接口来进行类比。脚本引擎通过引上下文对象来获取与脚本执行相关的信息,也允许开发人员通过此对象来配置脚本引擎的行为。该上下对象中主要包含以下3类信息。
7.2.1 输入与输出
首先介绍与脚本输入和输出相关的配置信息,其中包括脚本在执行中用来读取数据输入的java.io.Reader对象以及输出正确内容和出错信息的java.io.Writer对象。在默认情况下,脚本的输入输出都发生在标准控制台中,如果希望把脚本的输出写入到文件 中,可以使用如下代码。通过setWriter方法把脚本的输出重定向到一个文件 中。通过ScriptContext的setReader和setErrorWriter方法可以分别设置脚本执行时的数据输入来源和产生错误时出错信息的输出 目的。


代码如下:

public void scriptToFile()throws IOException,ScriptException{
        ScriptEngine engine = getJavaScriptEngine();
        ScriptContext context = engine.getContext();
        context.setWriter(new FileWriter("output.txt"));
        engine.eval("println('hello world!');");
        }

7.2.2 自定义属性

ScriptContext中也有与ServletContext中类似的获取和设置属性的方法,即setAttribute和getAttribute.所不同的是,ScriptContext中的属性是有作用域之分的。不同作用域的区别在于查找时的顺序不同,每个作用域都以一个对应的整数表示其查找顺序。该整数值越小,说明查找时的顺序越优先。优先级高的作用域中的属性会隐藏优先级低中的同名属性。因此,设置属性时需要显式指定所在的作用域。在获取属性的时候,即可选择指定的作用域中查找,也可以选择根据作用域优先级自动进行查找。
不过脚本执行上下文实现 中包含的作用域是固定的。开发人员不能随意定义自己的作用域。通过ScriptContext的getScopes方法可以得到所有可用的作用域列表。SciptContext中预先定义了两个作用域:常量ScriptContext.ENGINE_SCOPE表示的作用域对应的是当前的脚本引擎,而ScriptContext.GLOBAL_SCOPE表示的作用域对应的是从同一引擎工厂中创建出来的所有脚本引擎对象。前者的优先级较高。如下例:


代码如下:

public void scriptContextAttribute(){
        ScriptEngine engine = getJavaScriptEnging();
        ScriptContext context = engine.getContext();
        context.setAttribute("name","World",ScriptContext.GLOBAL_SCOPE);
        context.setAttribute("name","Bob",ScriptContext.ENGINE_SCOPE);
        context.getAttribute("name");//值为Bob
        }

7.2.3 语言绑定对象

脚本执行上下文中的最后一类信息是语言绑定对象。语言绑定对象也是与作用域相对应的。同样的作用域优先级顺序对语言绑定对象也适用。这样的优先级顺序会对脚本执行时的变量解析产生影响。如下例:


代码如下:

public void scriptContextBindings()throws ScriptException
    {
    ScriptEngine engine = getJavaScriptEnging();
    ScriptContext context = engine.getContext();
    Bindings bindings1 = engine.createBindings();
    bindings1.put("name","World");
    context.setBindings(bindings1,ScriptContext.GLOBAL_SCOPE);
    Bindings bindings2 = engine.createBindings();
    bindings2.put("name","Bob");
    context.setBindings(bindings2,ScriptContext.ENGINE_SCOPE);
    engine.eval("println(name);");//结果为Bob
    }

还可以Bindings bindings = context.getBindings(ScriptContext.ENGINE_SCOPE);

bindings.put("name","World")
engine.eval("println(name);");

7.3 脚本的编译:
脚本语言一般是解释执行的。脚本引擎在运行时需要先解析脚本之后再执行。一般来说,通过解释执行的方式运行脚本的速度比编译之后再运行会慢一些。当一段脚本需要被多次重复执行时,可以先对脚本进行编译。编译之后的脚本执行时不需要重复解析,可以提高执行效率。不是所有脚本引擎都支持对脚本进行编译。如果脚本引擎支持这一特性,它会实现javax.script.Compilable接口来声明这一点。脚本引擎的使用者可以利用这个能力来提高需要多次执行的脚本的运行效率。Java SE中自带的JavaScript脚本引擎是支持对脚本进行编译的。
如下代码中,Compilable接口的compile方法用来对脚本代码进行编译,编译的结果用javax.script.CompiledScript来表示。由于不是所有的脚本引擎都支持Compilable接口,因此这里需要用instanceof进行判断。在run方法中,通过CompiledScript的eval方法就可以执行脚本。代码中把一段脚本重复执行了100次,以此说明编译完的脚本在重复执行时的性能优势。


代码如下:

public CompiledScript compile(String scriptText) throws ScriptException {
        ScriptEngine engine = getJavaScriptEngine();
        if (engine instanceof Compilable) {
            CompiledScript script = ((Compilable) engine).compile(scriptText);
        }
        return null;
    }

public void run(String scriptText) throws ScriptException {
        CompiledScript script = compile(scriptText);
        if (script == null) {
            return;
        }
        for (int i = 0; i < 100; i++) {
            script.eval();
        }
    }

CompiledScript的eval方法所接受的参数与ScriptEngine的eval方法是相同的。

7.4 脚本中方法调用
在脚本中,最常见的和最实用的就是方法。有些脚本引擎允许使用者单独调用脚本中某个方法。支持这种方法调用方式的脚本引擎可以实现javax.script.Invocable接口。通过Invocable接口可以调用脚本中的顶层方法,也可以调用对象中的成员方法。如果脚本中顶层方法或对象中的成员方法实现了Java中的接口,可以通过Invocable接口中的方法来获取脚本中相应的Java接口的实现对象。这样就可以在Java语言中定义接口,在脚本中实现接口。程序中使用该接口的其他部分代码并不知道接口是由脚本来实现的。与Compilable接口一样,ScriptEngine对于Invocable接口的实现也是可选的。
下面代码通过Invocable接口的invokeFunction来调用脚本中的顶层方法,调用时的参数会被传递给脚本中的方法。因为JavaSE自带的JavaScript脚本引擎实现了Invocable接口,所以这里省去了对引擎是否实现了Invocalbe接口的判断
在java中调用脚本顶层方法的示例:


代码如下:

public void invokeFunction()throws ScriptException,NoSuchMethodException{
        ScriptEngine engine = getJavaScriptEngine();
        String scriptText ="function greet(name) { println('hello,'+name );}";
        engine.eval(scriptText);
        Invocable invocable=(Invocable)engine;
        invocable.invokeFunction("greet","World");
        }

如果被调用方法是脚本中对象的成员方法,就需要使用invokeMethod方法,如下面代码中所示,代码中getGreeting方法是属于对象obj的,在调用的时候需要把这个对象作为参数传递进去。

//在Java中调用脚本对象的成员方法的示例


代码如下:

public void inokeMethod()throws ScriptException,NoSuchMethodException
    {
    ScriptEngine engine = getJavaScriptEngine();
    String scriptText = "var obj={ getGreeting:function(name){return 'Hello,'+name;}};";
    engine.eval(scriptText);
    Invocable invocable = (Invocable)engine;
    Object scope = engine.get("obj");
    Object result = invocable.invokeMethod(scope,"getGreeting","Alxx");
    System.out.println(result);
    }

方法invokeMethod与方法invokeFunction用法差不多,区别在于invokeMethod要指定包含待调用方法的对象。

7.5 脚本中实现java接口

在有些脚本引擎中,可以在Java语言中定义接口,并在脚本中编写接口的实现,这样程序中的其他部分可以只同Java接口交互,并不需要关心接口是由什么方式来实现的。在下面代码中Greet是用Java定义的接口,其中包含一个getGreeting方法。在脚本中实现这个接口,通过getInterface方法可以得到由脚本实现的这个接口的对象,并调用其中的方法。


代码如下:

public void useInterface() throws ScriptException {
        ScriptEngine engine = getJavaScriptEngine();
        String scriptText = "function getGreeting(name){return 'Hello,'+name;}";
        engine.eval(scriptText);
        Invocable invocable = (Invocable) engine;
        Greet greet = invocable.getInterface(Greet.class);
        System.out.println(greet.getGreeting("World"));
    }

上面中的接口的实现是由脚本中的顶层方法来完成的。同样的,也可以由脚本中对象的成员方法来实现。对于这种情况,getInterface方法另外一种重载形式可以接受一个额外的参数来指定接口实现所在的对象。

由于脚本语言的语法简单和灵活,非常适用于没有或只有少量编程背景的用户来使用,这些用户可以通过脚本语言来定制程序的业务逻辑和用户界面等,通过脚本语言可以在程序的易用性和灵活性之间达到一个比较好的平衡。比如脚本语言Lua就被广泛应用在游戏开发中,用来对游戏的内部行为和用户界面进行定制。

8. 反射API在为Java程序带来灵活性的同时,也产生了额外的性能代价,由于反射API的实现机制,对于相同的操作,比如调用一个方法,用反射API来动态实现比直接在源代码中编写的方式大概慢一到两个数量级。随着Java虚拟机实现的改进,反射API的性能已经有了非常大的提升。但是这种性能的差距是客观存在的,因此,在某些对性能要求比较高的应用中,要慎用反射API。

(0)

相关推荐

  • 8个简单部分开启Java语言学习之路 附java学习书单

    之前为大家推荐了java语言阅读书籍,下面为大家介绍从哪几个方面开始学习java语言,具体内容如下 1. Java语言基础  谈到Java语言基础学习的书籍,大家肯定会推荐Bruce Eckel的<Thinking in Java>.它是一本写的相当深刻的技术书籍,Java语言基础部分基本没有其它任何一本书可以超越它.该书的作者Bruce Eckel在网络上被称为天才的投机者,作者的<Thinking in C++>在1995年曾获SoftwareDevelopment Jolt

  • Java语言简介(动力节点Java学院整理)

    Java 简介 Java是由Sun Microsystems公司(现已被oracle公司收购)于1995年5月推出的Java面向对象程序设计语言和Java平台的总称.由James Gosling和同事们共同研发,并在1995年正式推出,据oracle官方数据指数,目前全球已有上亿的系统是使用Java开发的. Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承.指针等概念,因此Java语言具有功能强大和简单易用两个特征.Java语言作为静态面向对象编程

  • Java老矣 尚能饭否?

    22 岁,对于一个技术人来说可谓正当壮年.但对于一门编程语言来说,情况可能又有不同.各类编程语言横空出世,纷战不休,然而 TIOBE 的语言排行榜上,Java 却露出了明显的颓势.这个老牌的语言,未来会是怎样? 写在前面 从 1995 年第一个版本发布到现在,Java 语言已经在跌宕起伏中走过了 22 年,最新的 Java 版本也已经迭代到 Java 9.当年 Java 语言的跨平台优势如今看来也只不过是家常小菜,Go.Rust 等语言横空出世,进一步拓宽了编程语言的边界.当年发明 Java 语

  • PHP和Java的主要区别有哪些?哪个最适合Web开发语言?

    一.前言 PHP和Java都是现在比较流行的二种编程语言. 对于许多新手来说,都会思考如果学的时候,该学哪种语言呢?下面这篇文章给大家整理两者的区别以及一些选择建议,一起来看看吧. 二.简介 PHP与Java作为两种截然不同的程序开发语言,无论是技术层面还是发展空间,亦或是市场份额占比,都有着不同的表现方式,理念上的不同导致了Java和PHP在Web应用开发上显示了不同的结果.若要一定追根到底,深究PHP与Java究竟哪个更好? 简而言之:PHP是一种解释执行的脚本语言,语法和C语言类似,易学易

  • Java基础知识之Java语言概述

    Java语言是SUN(Stanford University Network,斯坦福大学网络公司)公司1995年推出的一门高级编程语言,起初主要应用在小型消费电子产品上,后来随着互联网的兴起,Java语言迅速崛起(Java applet 可以在浏览器中运行),成为大型互联网项目的首选语言. 2009年04月20日,美国甲骨文公司74亿美元收购Sun,取得java的版权. Java 是面向对象的语言,没有面向对象编程经验的读者需要花费不少时间来了解面向对象的概念.语法和编程思想,有不能理解的地方请

  • JAVA语言编程格式高级规范

    作为一位开发人员,都要有严格的代码规范.为此我总结了一些代码规范案例. 目 录 1. 前言 2. 试用范围 3. JAVA命名规范-- 3.1 公共约定 3.2 Java文件.包 3.3 类.接口命名规范 3.4 方法命名规范 3.5 常量 3.6 变量和参数 3.7 组件/部件 3.8 集合 3.9 神秘的数 3.10 其他 3.11 Java异常 3.12 数组命名 3.13 数据库表命名规则 3.14 数据库字段命名规则 3.15 JSP文件命名 3.16 Servlet类命名 4. 书写

  • C++、C语言和JAVA开发的区别

    1.面向对象没有java彻底. 由于C++要兼容C的内容,而C是面向过程的,所以C++不可避免地出现过程影子,并不算是完全的面向对象的程序设计语言.例如总得要有main或winmain之类的过程吧. 2.C++的移植能力没有java好. 由于C++的事实标准的存在,即各个编译器总存在差异,所以或多或少存 在不兼容.而且各个软件平台的C++启动代码和硬件指令不同,编译后的C++程序一般是不能跨平台的.而java从娘胎里出来就是为了跨平台执行的,不采 用二进制机器码作为最终代码,所以在移植方面较好.

  • C语言与JAVA的区别是什么(推荐)

    首先来说说他们各自的历史:C语言的发展历史 C语言的发展颇为有趣.它的原型ALGOL 60语言.(也成为A语言) 1963年,剑桥大学将ALGOL 60语言发展成为CPL(Combined Programming Language)语言. 1967年,剑桥大学的Matin Richards 对CPL语言进行了简化,于是产生了BCPL语言. 1970年,美国贝尔实验室的Ken Thompson将BCPL进行了修改,并为它起了一个有趣的名字"B语言".意思是将CPL语言煮干,提炼出它的精华

  • Java程序与C语言的区别浅析

    Java和C语言虽有相同性,但两者也有一定的不同.Java程序是面向对象的一种简单.分布式 .解释.健壮.安全.结构中立.可移植.高效能.多线程.动态的语言它是面向对象而C语言是面向过程的,这是最大的不同,对于学过C语言的我们来说,Java可以说是比较简单的编程语言. 在Java语言中,所有的变量必须要首先声明,然后才能使用. Java中可以有若干类但有且只有一个public,一个类中至少含有一个main方法,否则程序不能运行.而一个C语言由若干函数构成,其中必须且只有一个main的主函数,程序

  • 深入Java7的一些新特性以及对脚本语言支持API的介绍

    1.switch条件语句中可以加入字符串了,实现方法是利用了字符串的hashcode()值作业真正的值2.增加了一种可以在字面量中使用的进制,二进制,通过在数字前面加"0b"或"0B"3.在数字字面量中使用下划线来分隔数字方便阅读,不影响数值大小.基本原则是前后都是数字的才可以出现下划线4.java7对异常做了两个改动: 4.1.支持在一个catch子句中同时捕获多个异常,另外一个是在捕获并重新抛出异常时的异常类型更加精确.java7中Throwable类增加add

  • java9新特性Reactive Stream响应式编程 API

    目录 一.Java9ReactiveStreamAPI 二.Java响应式编程四大接口 2.1.SubscriberInterface(订阅者订阅接口) 2.2.SubscriptionInterface(订阅令牌接口) 2.3.PublisherInterface(发布者接口) 2.4.ProcessorInterface(处理器接口) 二.实战案例 实现订阅者SubscriberInterface SubmissionPublisher消息发布者 我计划在后续的一段时间内,写一系列关于jav

  • java9新特性Reactive Stream响应式编程 API

    目录 一.Java9ReactiveStreamAPI 二.Java响应式编程四大接口 2.1.SubscriberInterface(订阅者订阅接口) 2.2.SubscriptionInterface(订阅令牌接口) 2.3.PublisherInterface(发布者接口) 2.4.ProcessorInterface(处理器接口) 二.实战案例 实现订阅者SubscriberInterface SubmissionPublisher消息发布者 我计划在后续的一段时间内,写一系列关于jav

  • ECMAScript6的新特性箭头函数(Arrow Function)详细介绍

    箭头函数是ECMAScript 6最受关注的更新内容之一.它引入了一种用「箭头」(=>)来定义函数的新语法,它-它碉堡了~.箭头函数与传统的JavaScript函数主要区别在于以下几点:1.对 this 的关联.函数内置 this 的值,取决于箭头函数在哪儿定义,而非箭头函数执行的上下文环境.2.new 不可用.箭头函数不能使用 new 关键字来实例化对象,不然会报错.3.this 不可变.函数内置 this 不可变,在函数体内整个执行环境中为常量.4.没有arguments对象.更不能通过ar

  • ThinkPHP3.1新特性之多层MVC的支持

    1.模型(Model)层:默认的模型层由Model类构成,但是随着项目的增大和业务体系的复杂化,单一的模型层很难解决要求,从3.1开始推出了多层Model的支持,设计思路很简单,不同的模型层仍然都继承自系统的Model类,但是在目录结构和命名规范上做了区分,例如在某个项目设计中需要区分数据层.逻辑层.服务层等不同的模型层,我们可以在项目的Lib目录下面创建Model.Logic和Service目录,把对用户表的所有模型操作分成三层: 数据层:Model/UserModel 用于定义数据相关的自动

  • ThinkPHP3.1新特性之对Ajax的支持更加完善

    ThinkPHP3.1版对AJAX的支持更加完善了,具体表现在: 1.判断AJAX方式改进 现在可以直接使用常量IS_AJAX来判断是否AJAX方式请求,用来取代之前的Action类的isAjax方法,优势是可以在任何代码里面进行判断.而Action类的error和success方法内置就支持对AJAX自动判断支持. 2.ajaxReturn方法完善 原来的ajaxReturn方法只能返回固定结构的数据,包括data.status和info索引信息,如果需要扩展额外的返回数据信息,只能通过aja

  • MySQL 5.7新特性介绍

    1. 介绍 身处MySQL这个圈子,能够切身地感受到大家对MySQL 5.7的期待和热情,似乎每个人都迫不及待的想要了解.学习和使用MySQL 5.7.那么,我们不禁要问,MySQL 5.7到底做了哪些改进,引入了哪些新功能,性能又提升了多少,能够让大家翘首以盼,甚至欢呼雀跃呢? 下面就跟随我来一起了解一下MySQL 5.7的部分新功能.想要在一篇文章中介绍完MySQL 5.7的所有改进,几乎是不可能的.所以,我会选择一些有特别意思的.特别有用的功能进行介绍.希望通过这篇文章,能够激发大家对My

  • SpringBoot2.3新特性优雅停机详解

    什么是优雅停机 先来一段简单的代码,如下: @RestController public class DemoController { @GetMapping("/demo") public String demo() throws InterruptedException { // 模拟业务耗时处理流程 Thread.sleep(20 * 1000L); return "hello"; } } 当我们流量请求到此接口执行业务逻辑的时候,若服务端此时执行关机 (ki

  • Spring Boot2.3 新特性分层JAR的使用

    背景 在我们实际生产容器化部署过程中,往往会遇到 Docker 镜像很大,部署发布很慢的情况 影响 docker 镜像大小的因素,主要有以下三个方面: 基础镜像的大小 .尽量选择 alpine 作为基础镜像 减少操作系统内置软件 Dockerfile 指令层数. 这就要求我们优化 Dockerfile 能合并在一行的尽量合并等 应用 jar 的大小.这是今天要分享的重点内容 helloworld 镜像 我们先来基于 spring boot 2.3.0 构建一个最简单的 web helloworl

  • 详解c++11新特性之模板的改进

    C++11关于模板有一些细节的改进: 模板的右尖括号 模板的别名 函数模板的默认模板参数 模板的右尖括号 C++11之前是不允许两个右尖括号出现的,会被认为是右移操作符,所以需要中间加个空格进行分割,避免发生编译错误. int main() { std::vector<std::vector<int>> a; // error std::vector<std::vector<int> > b; // ok } 这个我之前都不知道,我开始学编程的时候就已经是C

随机推荐