小编str*_*sus的帖子

在 Java 记录中强制执行不可变集合?

Java 记录用于实现浅不可变的数据载体类型。如果构造函数接受可变类型,那么我们应该实现显式防御性复制以强制不变性。例如

record Data(Set<String> set) {
    public Data(Set<Thing> set) {
        this.set = Set.copyOf(set);
    }
}
Run Code Online (Sandbox Code Playgroud)

这有点烦人 - 我们必须

  1. 实现一个老式的 POJO 构造函数(复制字段)而不是使用规范的构造函数和
  2. 显式初始化每个字段只是为了处理可变字段的防御性副本。

理想情况下,我们想要表达的是以下内容:

record SomeRecord(ImmutableSet<Thing> set) {
}
Run Code Online (Sandbox Code Playgroud)

或者

record SomeRecord(Set<Thing> set) {
    public SomeRecord {
        if(set.isMutable()) throw new IllegalArgumentException(...);
    }
}
Run Code Online (Sandbox Code Playgroud)

这里我们使用一个虚构的ImmutableSet类型和Set::isMutable方法,在任何一种情况下,记录都是使用规范构造函数创建的 - 很好。不幸的是它不存在!

据我所知,内置集合类型(在 Java 10 中引入)是隐藏的,即无法确定集合是否不可变(除了尝试修改它)。

我们可以使用 Guava,但是当 99% 的功能已经在核心库中时,这似乎有点过分了。或者,有 Maven 插件可以测试注释为不可变的类,但这又是一个创可贴而不是解决方案。

是否有任何纯 Java 机制来强制执行不可变集合?

java immutability java-record java-16

13
推荐指数
1
解决办法
261
查看次数

JNA将Java布尔值映射到-1整数吗?

boolean在JNA结构中传递值时,我正在使用的本机库收到令人惊讶的警告:

value of pCreateInfo->clipped (-1) is neither VK_TRUE nor VK_FALSE
Run Code Online (Sandbox Code Playgroud)

在此库中VK_TRUEVK_FALSE分别定义为1和0。

结构本身并不是特别复杂,其他所有功能似乎都可以正常工作(本机库似乎将“ undefined”布尔值视为false),但无论如何这里都是这样:

public class VkSwapchainCreateInfoKHR extends Structure {
    public int sType;
    public Pointer pNext;
    public int flags;
    public Pointer surface;
    public int minImageCount;
    public int imageFormat;
    public int imageColorSpace;
    public VkExtent2D imageExtent;
    public int imageArrayLayers;
    public int imageUsage;
    public int imageSharingMode;
    public int queueFamilyIndexCount;
    public Pointer pQueueFamilyIndices;
    public int preTransform;
    public int compositeAlpha;
    public int presentMode;
    public boolean clipped;       // <--------- this …
Run Code Online (Sandbox Code Playgroud)

java jna

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

将 JNA 结构的集合传递给本机方法

问题

我试图将一组 JNA 结构传递给本机方法,但事实证明它非常繁琐:

假设我们有一个结构:

class MyStructure extends Structure {
    // fields...
}
Run Code Online (Sandbox Code Playgroud)

和 JNA 接口中的一个方法:

void pass(MyStructure[] data);
Run Code Online (Sandbox Code Playgroud)

它映射到本机方法:

void pass(const MYStructure* data);
Run Code Online (Sandbox Code Playgroud)

现在的复杂之处在于应用程序正在动态构建这些结构的集合,即我们不是在处理静态数组,而是在处理类似这样的事情:

class Builder {
    private final Collection<MyStructure> list = new ArrayList<>();

    // Add some data
    public void add(MyStructure entry) {
        list.add(entry);
    }

    // Pass the data to the native library
    public void pass() {
        // TODO
    }
}
Run Code Online (Sandbox Code Playgroud)

pass()方法的一个简单实现可能是:

MyStructure[] array = list.toArray(MyStucture[]::new);
api.pass(array);
Run Code Online (Sandbox Code Playgroud)

libJNA 库接口在哪里)。

当然这不起作用,因为数组不是连续的内存块 - 足够公平。

垃圾解决方案#1

一种解决方案是从结构实例分配一个 JNA …

java jna

5
推荐指数
0
解决办法
280
查看次数

标签 统计

java ×3

jna ×2

immutability ×1

java-16 ×1

java-record ×1