我在我的代码中使用 Java 15 预览功能记录,并将记录定义如下
public record ProductViewModel
(
String id,
String name,
String description,
float price
) {
}
Run Code Online (Sandbox Code Playgroud)
在控制器级别我有以下代码
@Put(uri = "/{id}")
public Maybe<HttpResponse> Update(ProductViewModel model, String id) {
LOG.info(String.format("Controller --> Updating the specified product"));
return iProductManager.Update(id, model).flatMap(item -> {
if(item == null)
return Maybe.just(HttpResponse.notFound());
else
return Maybe.just(HttpResponse.accepted());
});
}
Run Code Online (Sandbox Code Playgroud)
模型中的 UI没有传递id的值,但是,它作为路由参数传递。现在我想在控制器级别设置值,比如
model.setid(id) // Old style
Run Code Online (Sandbox Code Playgroud)
如何将值设置为记录特定属性
Java 14 带来了记录,这是许多函数式语言中的一个很好的补充:
爪哇:
public record Vehicle(String brand, String licensePlate) {}
Run Code Online (Sandbox Code Playgroud)
毫升:
type Vehicle =
{
Brand : string
LicensePlate : string
}
Run Code Online (Sandbox Code Playgroud)
在 ML 语言中,可以通过创建一个更改了一些值的副本来“更新”记录:
let u =
{
Brand = "Subaru"
LicensePlate = "ABC-DEFG"
}
let v =
{
u with
LicensePlate = "LMN-OPQR"
}
// Same as:
let v =
{
Brand = u.Brand
LicensePlate = "LMN-OPQR"
}
Run Code Online (Sandbox Code Playgroud)
这在 Java 14 中可能吗?
假设 JSON 结构具有多个可选字段。通过课程,你可以做类似的事情
public static final class Foo {
@JsonProperty("x")
private int x = 1;
@JsonProperty("y")
private int y = 2;
@JsonProperty("z")
private int z = 3;
}
Run Code Online (Sandbox Code Playgroud)
它定义了字段的默认值,以防它不存在于提供的 json 中。这也可以用记录来完成吗?
public record Foo(int x, int y, int z) {
}
Run Code Online (Sandbox Code Playgroud)
构造函数重载显然不是一个选项,据我所知,无论如何你只能有一个@JsonCreator注释。
自定义反序列化器应该可以解决这个问题,但是有没有其他方法,比如提供一个默认值的注释,以在记录的构造函数中使用,以防 json 中未提供该值?
给定一个带有 final 字段的简单类,例如 a String(参见下面的示例)或 Spring 依赖项,使用 Java 14 记录使其更简洁并可能删除 Lombok 等注释处理器是个好主意吗?
根据JEP描述记录,“记录使语义声明成为其数据的简单、透明的持有者”。
显然,只有 final 字段的泛型类并不是其数据的透明持有者,并且在使用记录时,其final变量是公开的,这可能是不可取的。但是,在许多情况下,这可能不是主要问题。
因此,这是否“足以”将其视为对该语言功能的“滥用”?或者还有其他不那么明显的缺点吗?
@RequiredArgsConstructor // or an explicit constructor when not using lombok
class AudienceValidator implements OAuth2TokenValidator<Jwt> {
private final String audience;
public OAuth2TokenValidatorResult validate(Jwt jwt) {
// validate
}
}
record AudienceValidator(String audience) implements OAuth2TokenValidator<Jwt> {
public OAuth2TokenValidatorResult validate(Jwt jwt) {
// validate
}
}
Run Code Online (Sandbox Code Playgroud) 最近我正在创建另一种枚举类型。我利用了这样一个事实,即在 Java 中,枚举是一种特殊类型的类(而不是命名的整数常量,就像在 C# 中一样)。我用两个字段制作了它,一个全参数构造函数和两个字段的 getter。
这是一个例子:
enum NamedIdentity {
JOHN(1, "John the Slayer"),
JILL(2, "Jill the Archeress");
int id;
String nickname;
NamedIdentity(int id, String nickname) {
this.id = id;
this.nickname = nickname;
}
id id() {
return this.id;
}
String nickname() {
return this.nickname;
}
}
Run Code Online (Sandbox Code Playgroud)
然后我认为 Java 14 的record关键字可以为我节省此功能试图拯救我的样板代码。据我所知,这不与enums结合。如果enum record已经存在,则上述代码将如下所示:
enum record NamedIdentity(int id, String nickname) {
JOHN(1, "John the Slayer"),
JILL(2, "Jill the …Run Code Online (Sandbox Code Playgroud) 我有一个用于定义方法或字段的注释,如下所示:
@Retention(RetentionPolicy.RUNTIME)
@Target(value = {ElementType.METHOD, ElementType.FIELD})
public @interface NotColumn {
}
Run Code Online (Sandbox Code Playgroud)
我想阻止用户在记录上使用此注释,因为在该上下文中使用此注释没有意义。看来这样做不应该编译,因为我没有指定ElementType.PARAMETER为有效的@Target.
不过,以下编译良好:
public record MyRecord(String customerId,
String companyName,
@NotColumn String description
}
Run Code Online (Sandbox Code Playgroud)
但是这种带有紧凑构造函数的形式无法使用“ java:注释类型不适用于这种声明”进行编译 - 这实际上是我所期望的。
public record MyRecord(String customerId,
String companyName,
@NotColumn String description
public MyRecord {
}
}
Run Code Online (Sandbox Code Playgroud) 记录是Java 16的一项新功能。在JEP 395:记录中定义。
假设您有这样的记录。
public record Person(String last, String first, int age)
{
public Person()
{
this("", "", 0);
}
}
Run Code Online (Sandbox Code Playgroud)
这是最后一堂课。它自动生成 getter 方法first()、last() 和age()。
现在这是 JavaFX 中的 TableView。
/**************************************************
* Author: Morrison
* Date: 10 Nov 202021
**************************************************/
import javafx.application.Application;
import javafx.application.Platform;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.control.TableView;
import javafx.scene.control.TableColumn;
import javafx.scene.control.cell.PropertyValueFactory;
public class TV extends Application
{
public TV()
{
}
@Override
public void init()
{
}
@Override
public void start(Stage primary) …Run Code Online (Sandbox Code Playgroud) 我刚刚尝试将我的项目升级到 Java 15,现在出现以下错误:
both interface org.jooq.Record in org.jooq and class java.lang.Record in java.lang match
Run Code Online (Sandbox Code Playgroud)
有没有人有解决这个问题的经验?
尝试使用record和记录组件的一些代码。我正在使用变量 rarity 组件,并且在自定义构造函数上遇到了编译时错误。
public record Break<R extends Record>(R record, String... notifications) {
public Break(R record, String... notifications) {
System.out.println("record: " + record + " and notifications: " + Arrays.toString(notifications));
this.record = record;
this.notifications = notifications;
}
// compile error: non canonical record constructor must delegate to another costructor
public Break(R record) {
System.out.println("record: " + record);
this.record = record;
}
public Break() {
this(null); // this works
// actually intelliJ suggests it uses the constructor that is not …Run Code Online (Sandbox Code Playgroud) 在这篇关于可序列化记录的文章中指出
反序列化通过调用记录类的规范构造函数来创建新的记录对象,将从流中反序列化的值作为参数传递给规范构造函数。这是安全的,因为这意味着记录类可以在将值分配给字段之前对其进行验证,就像普通 Java 程序通过 new 创建记录对象一样。“不可能”的对象是不可能的。
这与仅用于验证的构造函数争论。然而,当构造函数操作参数时,这会导致相当奇怪的行为。考虑这个非常人为的简单示例:
以下记录a在保存之前进行操作:
import java.io.Serializable;
public record TRecord (int a) implements Serializable {
public TRecord {
a = a-1;
}
}
Run Code Online (Sandbox Code Playgroud)
下面的程序只是在第一次保存序列化记录并在随后的时间加载它:
import java.io.*;
public class TestRecords {
public static void main(String args[]) {
TRecord a1 = null;
try {
FileInputStream fileIn = new FileInputStream("tmp");
ObjectInputStream in = new ObjectInputStream(fileIn);
a1 = (TRecord) in.readObject();
in.close();
fileIn.close();
} catch (IOException | ClassNotFoundException i) {
// ignore for now
}
if (a1 == …Run Code Online (Sandbox Code Playgroud)