一、Java21新特性
1、字符串模版
字符串模版可以让开发者更简洁的进行字符串拼接(例如拼接sql,xml,json等)。该特性并不是为字符串拼接运算符+提供的语法,也并非为了替换StringBuffer和StringBuilder。
利用STR模版进行字符串与变量的拼接
java
public class StringTest {
public static void main(String[] args) {
String sport="basketball";
String msg=STR."I like \{sport}";
System.out.println(msg);
}
}
预览功能(java文件不要加package包信息)
java
$>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,是一个接口。
java
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中可以进行基本的运算(支持三元运算)
java
int x=10,y=20;
String result=STR."\{x} + \{y} = \{x+y}";
System.out.println(result);//10 + 20 = 30
调用方法
java
String res=STR."获取一个随机数:\{Math.random()}";
System.out.println(res);
获取属性
java
String res1=STR."int的最大值是:\{Integer.MAX_VALUE}";
System.out.println(res1);
查看时间
java
String res2=STR."现在时间:\{new SimpleDateFormat("yyyy-MM-dd").format(new Date()) }";
System.out.println(res2);
计数操作
java
int index=0;
String result=STR."\{index++},\{index++},\{index++}";
System.out.println(result);
获取数组数据
java
String[] cars ={"bmw","ben","audi"};
String result = STR. "\{ cars[0] },\{ cars[1] },\{ cars[2] }" ;
System.out.println(result);
拼接多行数据
java
String[] cars ={"bmw","ben","audi"};
String result = STR. """
\{cars[0] }
\{ cars[1] }
\{ cars[2] }
""" ;
System.out.println(result);
自定义模版
java
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对象就可以了。
一个程序员最重要的能力是:写出高质量的代码!!
有道无术,术尚可求也,有术无道,止于术。
无论你是年轻还是年长,所有程序员都需要记住:时刻努力学习新技术,否则就会被时代抛弃!