标签: Java

  • Java 多行字符串字面量——Text Blocks

    JDK 15 引入了多行字符串字面量(Text Blocks)特性,不再需要采用字符串拼接的方式来在 Java 代码中定义多行字符串,同时也不需要对字符串内部的双引号做转义,让代码有更好的可读性和可维护性。

    使用

    定义一个 Text Block 很简单,采用三个双引号 """ (开始分隔符)来开头,后面可跟空白符,然后换行开始输入内容,可以换行或输入直接输入双引号,最后用三个双引号""" (结束分隔符)结束。

    Text Block 的内容从开始分隔符后第一个换行符的下一个字符串开始,到结束分隔符前一个字符结束。

    var s = """
            <html>
                <body>
                    <p>Hello, world!</p>
                </body>
            </html>
            """;
    

    最后将得到,其中用.来代表空格,可以看到保持了多行,并且保持了缩进(注意,最后有一个空行)。

    <html>
    ....<body>
    ........<p>Hello,.world!</p>
    ....</body>
    </html>
    
    

    (更多…)

  • Java module

    模块的主要作用有:

    • 模块间需要显示地声明(模块)依赖,而不是以前的简单的基于 classpath
    • 更强的封装隔离,模块不主动导出的话无法被 import;不 open 则无法对其使用反射技术

    指令

    模块通过在模块根目录下的 module-info.java 中的指令来约束使用。

    定义模块

    最好(或则是必须,没找到规定说明) moduleName 和文件夹名称一致,否则 javac 编译时提示 module 和预期的不一致

    module moduleA {
    }
    

    引入依赖

    requires moduleB;
    

    可加 transitive 来表示依赖传递,如 requires transitive moduleB;,然后在 moduleCrequires moduleA; 后,那么在 moduleC 中可使用在 moduleB 中导出的类或接口。

    导出 package

    exports packageFullName;
    

    表示当别的模块(A) requires 了当前模块,那么 packageFullName 这个包(及子孙包)里的 publicprotected 的类和接口可在模块 A 里被访问使用。

    可用 exports packageFullName to moduleA, moduleB 来表示仅 moduleAmoduleB 可访问 packageFullName

    提供服务

    provides full.name.Service with full.name.concreateService, full.name.concreateService2;
    

    表示该模块向外提供 full.name.Service 的实现 full.name.concreateServicefull.name.concreateService2

    使用服务

    uses full.name.Service;
    

    表示该模块需要使用 full.name.Service。同时,不直接依赖具体的实现,而是使用抽象类或接口。然后搭配 ServiceLoader 或别的 IoC 工具来做依赖注入,从而达到和具体实现解耦的目的。

    配合反射

    opens fullPackageName;
    

    表示 fullPackageName 可被使用反射技术。也可使用 opens fullPackageName to moduleA, moduleB 限定开放反射的范围。

    open module moduleD {} 表示整个模块都是开放的。

    其它

    java --list-modules 查看 JDK 内置的模块

    编译运行

    可通过 javac -d mods --module-source-path src $(find src -name "*.java") 来编译运行(多个模块),src 表示各模块所在的目录。

    也可使用 javac -d dist --module-source-path src -m client 来编译指定的模块。

    (更多…)

  • Java main函数为何为static

    前几天,曾同学问我为什么 Java main 函数带有 static,我一时也不明白,只好说是 Java 的 main 函数的格式是规定的,我也一直这样写下来,然后赶紧去查。

    原谅我,我忘记这是在哪个网站/论坛找到的了,因为当时没记录,只有在聊天记录中找到了当时copy下来的我觉得可以说得过去的解释。

    The method is static because otherwise there would be ambiguity: which constructor should be called? Especially if your class looks like this:

    public class JavaClass{
        protected JavaClass(int x){}
        public void main(String[] args){
        }
    }
    

    (更多…)