一、Java21新特性

1、字符串模版

        字符串模版可以让开发者更简洁的进行字符串拼接(例如拼接sql,xml,json等)。该特性并不是为字符串拼接运算符+提供的语法,也并非为了替换StringBuffer和StringBuilder。

利用STR模版进行字符串与变量的拼接

public class StringTest {
    public static void main(String[] args) {
        String sport="basketball";
        String msg=STR."I like \{sport}";
        System.out.println(msg);
    }
}
预览功能(java文件不要加package包信息)
$>javac --enable-preview -source 21 StringTest.java
注: StringTest.java 使用 Java SE 21 的预览功能。
注: 有关详细信息,请使用 -Xlint:preview 重新编译。
$>java --enable-preview  StringTest
I like basketball

上面使用的STR是java中定义的模版处理器,它可以将变量的值取出,完成字符串的拼接。在每个java源文件中都引入了一个public static final修饰的STR属性,STR通过打印STR可以知道它是java.lang.StringTemplate,是一个接口。

Processor<String, RuntimeException> STR = StringTemplate::interpolate;


    default String interpolate() {
        return StringTemplate.interpolate(fragments(), values());
    }

    static String interpolate(List<String> fragments, List<?> values) {
        Objects.requireNonNull(fragments, "fragments must not be null");
        Objects.requireNonNull(values, "values must not be null");
        int fragmentsSize = fragments.size();
        int valuesSize = values.size();
        if (fragmentsSize != valuesSize + 1) {
            throw new IllegalArgumentException("fragments must have one more element than values");
        }
        JavaTemplateAccess JTA = SharedSecrets.getJavaTemplateAccess();
        return JTA.interpolate(fragments, values);
    }

    public static JavaTemplateAccess getJavaTemplateAccess() {
        var access = javaTemplateAccess;
        if (access == null) {
            try {
                Class.forName("java.lang.runtime.TemplateSupport", true, null);
                access = javaTemplateAccess;
            } catch (ClassNotFoundException e) {}
        }
        return access;
    }


final class TemplateSupport implements JavaTemplateAccess {
...
    @Override
    public String interpolate(List<String> fragments, List<?> values) {
        int fragmentsSize = fragments.size();
        int valuesSize = values.size();
        if (fragmentsSize == 1) {
            return fragments.get(0);
        }
        int size = fragmentsSize + valuesSize;
        String[] strings = new String[size];
        int i = 0, j = 0;
        for (; j < valuesSize; j++) {
            strings[i++] = fragments.get(j);
            strings[i++] = String.valueOf(values.get(j));
        }
        strings[i] = fragments.get(j);
        return JLA.join("", "", "", strings, size);
    }

其他使用示例,在STR中可以进行基本的运算(支持三元运算)

int x=10,y=20;
String result=STR."\{x} + \{y} = \{x+y}";
System.out.println(result);//10 + 20 = 30

调用方法

String res=STR."获取一个随机数:\{Math.random()}";
System.out.println(res);

获取属性

String res1=STR."int的最大值是:\{Integer.MAX_VALUE}";
System.out.println(res1);

查看时间

String res2=STR."现在时间:\{new SimpleDateFormat("yyyy-MM-dd").format(new Date()) }";
System.out.println(res2);

计数操作

int index=0;
String result=STR."\{index++},\{index++},\{index++}";
System.out.println(result);

获取数组数据

String[] cars ={"bmw","ben","audi"};
String result = STR. "\{ cars[0] },\{ cars[1] },\{ cars[2] }" ;
System.out.println(result);

拼接多行数据

String[] cars ={"bmw","ben","audi"};
String result = STR. """
        \{cars[0] }
        \{ cars[1] }
        \{ cars[2] }
        """ ;
System.out.println(result);

自定义模版

    public static void main(String[] args) {
        var INTER = StringTemplate.Processor.of((StringTemplate st) -> {
            StringBuilder sb = new StringBuilder();
            Iterator<String> iterator = st.fragments().iterator();
            for (Object value : st.values()) {
                sb.append(iterator.next());
                sb.append(value);
            }
            sb.append(iterator.next());
            return sb.toString();
        });
        int x = 10, y = 20;
        String result = INTER. "\{ x } + \{ y } = \{ x + y }" ;
        System.out.println(result);
    }

2、scoped values

scoped values是一个隐藏的方法参数,只有方法可以访问scoped values,它可以让两个方法之间传递参数时无需声明形参。例如在UserDao类中编写savaUser方法,LogDao类中编写了saveLog方法,那么在保存用户的时候需要保证事务,此时就需要在service层获取Connection对象,然后将该对象分别传入到两个Dao的方法中,但对于savaUser方法来说并不是直接使用Connection对象,却又不得不在方法的形参中写上该对象,其实仅从业务上来看,该方法中只要传入User对象就可以了。

Java17-20新特性

一个程序员最重要的能力是:写出高质量的代码!!
有道无术,术尚可求也,有术无道,止于术。
无论你是年轻还是年长,所有程序员都需要记住:时刻努力学习新技术,否则就会被时代抛弃!

11-05 17:54