标签: java-16

Record 无法从构造函数获取参数名称?

想看看如何在 Java 16(和 15 个相同的行为)下使用带有反射的 Records

public record RecordTest2(int id, int something, double total, LocalDateTime createdOn) {

    public RecordTest2(int id, int something, double total) {
        this(id, something, total, LocalDateTime.now());
    }
}
Run Code Online (Sandbox Code Playgroud)

查看规范构造函数,我确实看到了参数名称,但没有看到其他参数名称。

var recordTest2 = new RecordTest2(1, 2, 3.0, LocalDateTime.now());
Class<?> objectClass = recordTest2.getClass();

Constructor<?>[] constructors = objectClass.getConstructors();

for (Constructor<?> con : constructors) {
    System.out.println(con.getName());
    Parameter[] parameters = con.getParameters();
    for (Parameter parameter : parameters) {
        System.out.printf("param: %s\n", parameter.getName());
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

net.sf.persism.dao.records.RecordTest2
param: arg0
param: arg1
param: arg2
net.sf.persism.dao.records.RecordTest2
param: …
Run Code Online (Sandbox Code Playgroud)

java constructor java-record java-16

11
推荐指数
1
解决办法
319
查看次数

Java 16 的 Stream.toList() 和 Stream.collect(Collectors.toList()) 的区别?

JDK 16 现在toList()直接在Stream实例上包含一个方法。在以前的 Java 版本中,您总是必须使用该collect方法并提供一个Collector实例。

新方法显然需要输入更少的字符。这两种方法是否可以互换,或者是否存在应该注意的细微差别?

var newList = someCollection.stream()
    .map(x -> mapX(x))
    .filter(x -> filterX(x))
    .toList();

// vs.

var oldList = someCollection.stream()
    .map(x -> mapX(x))
    .filter(x -> filterX(x))
    .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

(这个问题类似于会不会 Stream.toList() 比 Collectors.toList() 表现更好,但关注行为而不是(仅)关注性能。)

java java-stream collectors java-16

10
推荐指数
3
解决办法
1939
查看次数

C 样式数组不再处理记录

我以前使用过这个人为的代码

record Foo(int bar[]) {}
Run Code Online (Sandbox Code Playgroud)

这是利用 C 风格的数组符号。它在 Java 15 中编译得很好。

现在,突然之间,随着Java 16中记录的正式发布,它不再编译了。这是jshell的输出:

record Foo(int bar[]) {}
Run Code Online (Sandbox Code Playgroud)

为什么它在 Java 15 中编译,这是一个错误吗?出于好奇,为什么它在记录中不受支持,而在 Java 的其他任何地方都受支持?

我正在使用javac来自Adoptium(基于 OpenJDK)。

java arrays java-record java-15 java-16

9
推荐指数
1
解决办法
207
查看次数

IntelliJ JDK 16 Early Access - 成功了吗?工具.jar

有没有人使用 JDK 16 ( https://jdk.java.net/16/ ) 早期访问构建与 IntelliJ取得了任何成功?

我可以使用 JDK 15 早期访问版本,但是当我尝试 JDK 16 时,我收到一条错误消息:

Error: Cannot determine path to 'tools.jar' library for 16 (path/to/jdk-16)
Run Code Online (Sandbox Code Playgroud)

我所做的所有研究都表明 JDK 将 tools.jar 存储在 path/to/jdk-16/lib 文件夹中。问题是,tools.jar 也不在 JDK 15 包中,但 JDK 15 工作正常。

如果有人对如何解决此问题有任何线索,我将不胜感激。我仍在尝试,如果我弄明白了,我会更新这篇文章。

提前致谢。

java intellij-idea java-16

8
推荐指数
1
解决办法
5332
查看次数

java.lang.ExceptionInInitializerError 与 Java-16 | jlClassFormatError 可访问:模块 java.base 不会“打开 java.lang”到未命名的模块

cglib在 Maven 项目中有一个传递依赖项。尽管添加了我认为正确的内容,但--add-opens我无法让库与 Java 16 一起使用。

如何开始cglib使用 Java 16?我在github页面上提出了这个问题

最小可重现示例:

Main.java

import net.sf.cglib.proxy.Enhancer;

public class Main {
    public static void main(String[] args) {
        new Enhancer();
    }
}
Run Code Online (Sandbox Code Playgroud)

使用 Java 15:

javac -cp cglib-3.3.0.jar Main.java

java --add-opens java.base/java.lang=ALL-UNNAMED -cp cglib-3.3.0.jar:asm-7.1.jar:. Main

Picked up _JAVA_OPTIONS: -Duser.language=en -Duser.country=GB
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by net.sf.cglib.core.ReflectUtils$1 (file:/Users/rbain/Desktop/cglib-3.3.0.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain)
WARNING: Please consider reporting this to the maintainers of …
Run Code Online (Sandbox Code Playgroud)

java cglib java-16

8
推荐指数
1
解决办法
3904
查看次数

为什么 Java 记录的规范构造函数不能具有比记录级别更严格的访问权限?

我有一种情况,我希望特定类型的记录实例只能使用同一包内单独类中的工厂方法创建。这样做的原因是因为在创建记录之前我需要执行大量的验证。

记录旨在成为其验证字段的哑数据载体,但验证不能在记录的构造函数中进行,因为我们需要访问一些精心设计的验证器对象才能实际执行验证。

由于将验证器对象传递给记录构造函数意味着它们将构成记录状态的一部分,这意味着我们不能使用记录构造函数来执行记录的验证。

因此,我将验证提取到它自己的工厂中并编写了如下代码(工厂类和同一包中的记录):

package some.package;

// imports.....

@Component
class SomeRecordFactory {
    private final SomeValidator someValidator;
    private final SomeOtherValidator someOtherValidator;
    // Rest of the fields
    // ....

    // constructor  
    // ....


    public SomeRecord create(...) {
         someValidator.validate(....);
         someOtherValidator.validate(....);
         // .... other validation

         return new SomeRecord(...);
    }
}
Run Code Online (Sandbox Code Playgroud)
package some.package;

public record SomeRecord(...) {
    /* package-private */ SomeRecord {
    }
}
Run Code Online (Sandbox Code Playgroud)

无论出于何种原因,上述内容不适用于 IntelliJ 抱怨:

Compact constructor access level cannot be more restrictive than the record access level (public)
Run Code Online (Sandbox Code Playgroud)

我可以通过使用普通类(允许使用单个包私有构造函数)来避免这个问题,但希望更准确地将数据建模为记录。

为什么记录存在此限制?未来是否有取消此限制的计划?

java java-record java-16

7
推荐指数
3
解决办法
523
查看次数

与 flatMap 相比,为什么 mapMulti 需要类型信息

我想使用mapMulti而不是flatMap重构以下代码:

// using flatMap (version 1) => returns Set<Item>
var items = users.stream()
                 .flatMap(u -> u.getItems().stream())
                .collect(Collectors.toSet());
Run Code Online (Sandbox Code Playgroud)

进入这个(版本2):

// using mapMulti (version 2) => returns Set<Item>
var items = users.stream()
                 .<Item>mapMulti((u, consumer) -> u.getItems().forEach(consumer))
                 .collect(Collectors.toSet());
Run Code Online (Sandbox Code Playgroud)

两者都返回相同的元素。然而,我怀疑我是否真的应该用flatMap更冗长的mapMulti. 为什么需要在mapMuli( .<Item>mapMulti)之前添加类型信息。如果我不包含类型信息,它将返回一个Set<Object>. (如何)我可以简化吗mapMulti

java java-stream java-16 java-17

7
推荐指数
1
解决办法
715
查看次数

为什么 Stream#toList 的默认实现看起来过于复杂/次优?

查看 的实现Stream#toList,我只是注意到它看起来是多么复杂和次优。

就像上面的 javadoc 中提到的那样default,大多数实现都没有使用这个实现Stream,但是,在我看来,它本来可以是其他的。

来源

/**
 * Accumulates the elements of this stream into a {@code List}. The elements in
 * the list will be in this stream's encounter order, if one exists. The returned List
 * is unmodifiable; calls to any mutator method will always cause
 * {@code UnsupportedOperationException} to be thrown. There are no
 * guarantees on the implementation type or serializability of the returned List.
 *
 * <p>The returned instance …
Run Code Online (Sandbox Code Playgroud)

java java-stream java-16

6
推荐指数
1
解决办法
189
查看次数

Java 记录和字段注释

当我们在 Java 中使用类时,为每个类字段/方法添加 JavaDoc/注释非常简单:

class Product {
    //Product unique identifier
    private int id;
}
Run Code Online (Sandbox Code Playgroud)

如果我们将这些类迁移到 Java 记录,则不清楚在这种情况下编写注释/JavaDocs 的最佳实践是什么:

record Product(int id, String name, double price) {
}
Run Code Online (Sandbox Code Playgroud)

因为现在所有字段都在一行中声明。

java java-14 java-record java-16

6
推荐指数
2
解决办法
209
查看次数

从 OpenJDK16 读取使用 keytool 创建的 PKCS12 密钥库时 Java 8 中的 IOException

TL; 博士

keytool从 OpenJDK16 创建的 PKCS12 密钥库文件无法从 Java 8、9、10 和 11 中读取。这是错误吗?如何创建适用于 Java 8 的 PKCS12 密钥库?

语境

我构建了一个 Maven 项目,该项目生成一个可执行 JAR 文件,该文件必须在从版本 8 到版本 16 的任何 JRE 上运行。该 JAR 文件生成一个 HTTPS 服务器(使用com.sun.net.httpserver.HttpsServer)。

在构建期间,我使用keytool生成密钥对并将其存储在捆绑在 JAR 中的 PKCS12 密钥库中(实际上,我使用的是keytool-maven-plugin):

$ /path/to/jdk16/bin/keytool -genkeypair -keystore /tmp/keystore.p12 -storepass password -storetype PKCS12 -alias https -dname "CN=localhost, OU=My HTTP Server, O=Sentry Software, C=FR" -keypass password -validity 3650 -keyalg RSA -sigalg SHA256withRSA
Run Code Online (Sandbox Code Playgroud)

Java 代码使用这个自动生成的密钥库来启动 HTTPS 服务器:

// initialize the HTTPS …
Run Code Online (Sandbox Code Playgroud)

java ssl keytool java-16

6
推荐指数
1
解决办法
561
查看次数