在使用Mory yLayout::varHandle构造varHandle时,我传入了一个自组装的对象数组,以实现构造内存段的公共方法.但我发现它似乎阻止了我使用对象数组而不是可变array.

代码片段如下所示.

public static MemorySegment buildMemorySegment(Object object, MemorySegment memorySegment, MemoryLayout originMemoryLayout, MemoryLayout memoryLayout, List<PathElement> pathElements, List<Object> indexParams) throws NoSuchFieldException, IllegalAccessException {
    Class<?> aClass = object.getClass();
    if (memoryLayout instanceof SequenceLayout sequenceLayout) {
        pathElements.add(PathElement.sequenceElement());
        for (int i = 0; i < sequenceLayout.elementCount(); i++) {
            Object[] array;
            if (Collection.class.isAssignableFrom(aClass)) {
                assert object instanceof Collection<?>;
                Collection<?> collection = (Collection<?>) object;
                array = collection.toArray();
            } else {
                assert object instanceof Object[];
                array = ((Object[]) object);
            }
            Object o = array[i];
            indexParams.add((long) i);
            buildMemorySegment(o, memorySegment, originMemoryLayout, sequenceLayout.elementLayout(), pathElements, indexParams);
            indexParams.removeLast();
        }
        pathElements.removeLast();
    } else if (memoryLayout instanceof StructLayout structLayout) {
        List<MemoryLayout> memoryLayouts = structLayout.memberLayouts();
        for (MemoryLayout layout : memoryLayouts) {
            String layoutName = layout.name().orElseThrow();
            pathElements.add(PathElement.groupElement(layoutName));
            Field declaredField = aClass.getDeclaredField(layoutName);
            Object fieldValue = getFieldValue(object, declaredField);
            buildMemorySegment(fieldValue, memorySegment, originMemoryLayout, layout, pathElements, indexParams);
            pathElements.removeLast();
        }
    } else if (memoryLayout instanceof ValueLayout) {
        Object[] varParams = new Object[indexParams.size() + 2];
        varParams[0] = memorySegment;
        for (int i = 0; i < indexParams.size(); i++) {
            varParams[i + 1] = indexParams.get(i);
        }
        varParams[varParams.length - 1] = object;
        VarHandle varHandle = originMemoryLayout.varHandle(pathElements.toArray(new PathElement[0]));
        varHandle.set(varParams);
    }
    return MemorySegment.NULL;
}

关键问题是我成功地构建了内存布局,并通过解析内存布局来控制varHandle参数,从而构建了varHandle.出现了以下问题.

enter image description here

enter image description here

这就是我的调试程序所说的,我想要实现的是 varHandler.set(segment, (long)i, i);

我能实施我的 idea 吗?我该怎么做呢?

推荐答案

您不能将保存坐标的Object[]直接传递给VarHandle::set(因为它是一个signature polymorphic方法).

但是,您可以使用toMethodHandle将var句柄转换为方法句柄,然后使用invokeWithArguments:

MethodHandle setter = varHandle.toMethodHandle(VarHandle.AccessMode.SET);
setter.invokeWithArguments(varParams);

Java相关问答推荐

获取拦截器内部的IP地址

无法在Java中将hhmmss格式的时间解析为LocalTime

JUnit—如何模拟局部变量对象方法调用

使用联接和分页的SpringBoot Spring数据JPA

JVM会优化这个数学运算吗?

Hibernate 6支持Joda DateTime吗?

FALSE:它应该在什么时候使用?

为什么JAVA&S清洁器使用链表而不是并发HashSet?

如何在运行时动态创建表(使用Java、JPA、SprringBoot)

如何在构建Gradle项目时排除com.google.guava依赖项的一个变体

Lombok@Nonnull是否也对供应商有影响?

Quarkus:运行时出现EnumConstantNotPresentException

Android Studio模拟器没有互联网

根据应用程序 Select 的语言检索数据

如何利用OpenTelemeter将初始值(零)输出到普罗米修斯

在Spring Boot中使用咖啡因进行缓存

Java 21内置http客户端固定运营商线程

将基于实例编号的对象列表拆分为新的对象列表

ResponseEntity.控制器截断响应的JSON部分

将在 Docker 中运行的 Spring Boot 连接到在 Docker 中运行的 PostgreSQL,无需 compose 文件?