java - 多种类型的Java列表是否可能

标签 java spring spring-boot jpa java-8

昨天我偶然发现了一些我无法解释的奇怪的 Java/Spring/IntelliJ 行为。

这是一个用jdk1.8.0_152制作的Spring Boot应用。

我运行了这个简单的 SQL 来填充我的数据库:

CREATE TABLE TEST_ORGANIZATION
(
    ID NUMBER(19) NOT NULL,
    NAME VARCHAR(255) NOT NULL
);

INSERT INTO TEST_ORGANIZATION (ID, NAME) VALUES ('1', 'test1');
INSERT INTO TEST_ORGANIZATION (ID, NAME) VALUES ('2', 'test2');

这是我的实体类:

@Data
@NoArgsConstructor
@Entity
public class TestOrganization {

    @Id
    private Long id;

    @NotNull
    private String name;
}

还有我的 JPA 存储库:

public interface TestOrganizationRepository extends JpaRepository<TestOrganization, Long> {

    @Query("SELECT new map(id as key, name as value) FROM TestOrganization")
    List<Map<String, String>> findAllAndMapById();
}

这就是事情变得困惑的地方。 我已经编写了一个简单的单元测试来检查值,但事实证明它在第二个断言上失败了:

@Test
public void shouldGetDocumentByName() {
    List<String> values = testOrganizationRepository.findAllAndMapById()
            .stream()
            .flatMap( m -> m.values().stream() )
            .collect( Collectors.toList() );

    assertThat( values ).isNotEmpty();
    assertThat( values ).allMatch( n -> n instanceof String );
}

使用 IntelliJ 进行调试时,它显示,如下所示:

enter image description here

这怎么可能?为什么我可以在字符串列表中包含 Long 值?

还有:

 values.add(1L) // fails to compile
 values.get(0).getClass().name // returns java.lang.String
 values.get(1).getClass().name // returns java.lang.Long

最佳答案

这是可能的,因为 Java 中的类型删除。简而言之,这意味着在运行时 Java 不知道您的泛型类型,所以任何 List对象使用 Object 操作类型。泛型具有编译类型安全性。 但是您可以更详细地了解类型删除,例如 here .

您可以自己模拟的相同行为:

public static void main(String[] args) {
    List<String> list = new ArrayList<>();
    addToList(list);
    System.out.println(list);
}

private static void addToList(List list) {
    list.add(1L);
    list.add(42);
    list.add("String");
    list.add(new Runnable() {
        @Override
        public void run() {}
    });
}

只要您不尝试将列表条目作为字符串进行操作,此代码就可以正常工作。但是当你添加如下内容时:

for (String s : list) {
    System.out.println(s);
}

你会得到java.lang.ClassCastException .

因此在编译时,您使用 List<String> , 但在运行时,Java 只知道 List .

关于java - 多种类型的Java列表是否可能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52755349/

相关文章:

java - 如何创建从商店提款和送货到商店的方法

java - 如何在保持分页的同时在spring-boot中过滤页面?

java - 如何在Android中的SQLite数据库中查找TEXT或VARCHAR类型的特定列占用的内存(大小)?

java - Spring + hibernate : server receives correct JSON but Hibernate inserts null values

java - 为什么我在 JBoss7.1.EAP 中加载 applicationContext 时出现 java.lang.NoSuchMethodError

java - 使用 AbstractRoutingDataSource 动态更改数据库架构/目录

java - Spring Cloud 契约(Contract) : Write Contract Test for multiple consumer with different or partially different expectations

spring - 如何在 Spring-Boot 项目中编辑 Hibernate 设置?

Java 正则表达式调整

java - 无法在 Spring Boot 中自动注册类型(JPA/Joda/Jadira)