【杂谈】Unchecked cast: ‘java.lang.Object‘ to ‘T‘ 与单元测试

类型不兼容: 无法将java.lang.Object转换为T - Java 总结一下,当我们在Java中尝试将一个Object类型的对象转换为泛型T类型时,可能会遇到类型不兼容的错误。这是因为在泛型中,类型参数在编译时会被擦除为其上界类型,导致Object类型无法隐式转换为泛型类型。所以,当我们尝试将一个Object类型的对象传递给setContent()方法时,它无法隐式转换为泛型T类型,从而导致了类型不兼容的错误。在Java编程中,当我们尝试将一个Object类型的对象转换为泛型T类型时,可能会遇到类型不兼容的错误。让我们来看一个示例代码,深入了解这个问题,并探讨如何解决它。 阅读详情
AI摘要

本文记录了Java开发中的两个问题。一是使用泛型通配符进行类型转换时,IDE会报未选中强制转换警告,可通过添加注解或用泛型方法转换解决;二是介绍了用Mockito + Junit对顺序表和工具类进行单元测试,还阐述了相关概念、注解及方法的使用。

一些杂乱的小问题记录

1. Unchecked cast: ‘java.lang.Object’ to ‘T’

问题描述
有时,我们要自定义一些工具类、工具方法或数据结构,此时需要用到泛型。

我们指导泛型既可以指定类型,也可以作为通配符使用。有时,当我们使用通配符进行类型转换时,IDE会报:

Unchecked cast: 'java.lang.Object' to 'T' 

翻译过来就是:未选中强制转换:‘java.lang.Object’到’T’ 。
这只是个IDE的警告,一般情况下并不影响程序运行,但如果放到实际工作中,这个代码总是报黄,总是不舒服,也容易让人产生代码不规范的感觉。
i1

参考文章
知乎优秀参考文章

解决方案

  • 忽略:添加@SuppressWarnings(“unchecked”)注解。如果直接在单个方法添加这个注解,代表每次只是忽略。根据参考文章的说法,这种单次忽略治标不治本。如果我们可以确定要返回的类型,如List等,则可参考参考文章的做法。
	@Override
    @SuppressWarnings("unchecked")
    public T get(int i) {
        if(i < INIT_LENGTH || i > length-1){
            throw new ArrayIndexOutOfBoundsException();
        }
        return (T) getElements()[i];
    }
  • 使用泛型方法进行类型转换:参考文章提供了List/Map的类型转换。本文借助 Class.cast() 方法进行稍微安全一些的转换,但由于泛型的缘故,工具类依然需要添加上面的忽略注解
	@SuppressWarnings("unchecked")
    public static <T> T typeConversion(Object o, Class<?> tClass){
        return (T) tClass.cast(o);
    }
@Override
    public T get(int i) {
        if(i < INIT_LENGTH || i > length-1){
            throw new ArrayIndexOutOfBoundsException();
        }
        return GenericTypeChangeUtil.typeConversion(getElements()[i], getElements()[i].getClass());
}

2. 单元测试

问题描述
既然在上一小节我们做了一个类型转换方法,该方法又是个人在学习数据结构过程中,自己写的一个顺序表。那么总得测试一下这个顺序表是否可用。

本例我们就用 Mockito + Junit 进行单元测试吧

参考教程
bilibili-Mockito优秀教程

测试
顺序表源码:

import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * 顺序表的实现
 * @author Sharry
 * @since 2023/9/16
 */
public class SequenceTable<T> implements ISequenceTable<T> {

    /**
     * init length : 0
     */
    public final int INIT_LENGTH = 0;

    /**
     * hash code constant
     */
    public final int HASH_TIMES = 31;

    /**
     * array to store sequence data
     */
    private Object [] elements;

    /**
     * this sequence table's length
     */
    private int length;

    public SequenceTable(T[] elements) {
        this.elements = elements;
        this.length = elements.length;
    }

    public SequenceTable(int length) {
        this.elements = new Object[length];
        this.length = length;
    }

    public SequenceTable() {
        this.elements = new Object[INIT_LENGTH];
        this.length = INIT_LENGTH;
    }

    public SequenceTable(T[] elements, int length) {
        if(length < elements.length){
            throw new ArrayIndexOutOfBoundsException();
        }
        this.elements = elements;
        this.length = length;
    }

    public Object[] getElements() {
        return elements;
    }

    public void setElements(Object[] elements) {
        this.elements = elements;
    }

    public int getLength() {
        return length;
    }

    public void setLength(int length) {
        this.length = length;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (!(o instanceof SequenceTable)) {
            return false;
        }
        SequenceTable<?> that = (SequenceTable<?>) o;
        return getLength() == that.getLength() && Arrays.equals(getElements(), that.getElements());
    }

    @Override
    public int hashCode() {
        int result = Objects.hash(getLength());
        result =HASH_TIMES * result + Arrays.hashCode(getElements());
        return result;
    }

    @Override
    public String toString() {
        return "SequenceTable{" +
                "elements=" + Arrays.toString(elements) +
                ", length=" + length +
                '}';
    }

    @Override
    public boolean isEmpty() {
        if (elements.length == 0){
            return this.getLength() == INIT_LENGTH || this.getElements() == null;
        }
        for (Object element : elements) {
            if (null != element) {
                return false;
            }
        }
        return true;
    }

    @Override
    public int size() {
        return getLength();
    }

    @Override
    public T get(int i) {
        if(i < INIT_LENGTH || i > length-1){
            throw new ArrayIndexOutOfBoundsException();
        }
        return GenericTypeChangeUtil.typeConversion(getElements()[i], getElements()[i].getClass());
    }

    @Override
    public boolean set(int i, T x) {
        if(isOutOfBounds(i)){
            throw new ArrayIndexOutOfBoundsException();
        }
        Object[] eArr = getElements();
        Object e = getElements()[i];
        if ( e == null || !e.equals(x)) {
            eArr[i] = x;
            setElements(eArr);
            return true;
        }
        return false;
    }

    @Override
    public int insert(int i, T x) {
        if(isOutOfBounds(i)){
            throw new ArrayIndexOutOfBoundsException();
        }
        if(set(i,x)){
            return i;
        }
        return -1;
    }

    @Override
    public int insert(T x) {
        if(set(length-1,x)){
            return length-1;
        }
        return -1;
    }

    @Override
    public T remove(int i) {
        if(isOutOfBounds(i)){
            throw new ArrayIndexOutOfBoundsException();
        }
        Object e = getElements()[i];
        Object[] eArr = getElements();
        eArr[i] = null;
        setElements(eArr);
        return GenericTypeChangeUtil.typeConversion(e,e.getClass());
    }

    @Override
    public int search(T key) {
        Object[] eArr = getElements();
        for (int i = 0 ; i < eArr.length ; i++){
            boolean ifNull = eArr[i] != null && eArr[i] == key;
            if(ifNull || Objects.equals(eArr[i], key)){
                return i;
            }
        }
        return -1;
    }

    @Override
    public boolean contains(T key) {
        return search(key) != -1;
    }

    @Override
    public int insertDifferent(T x) {
        if(contains(x)){
            return -1;
        }
        insert(x);
        return length-1;
    }

    @Override
    public T remove(T key) {
        T element;
        if (!contains(key)) {
            return null;
        } else {
            element = GenericTypeChangeUtil.typeConversion(getElements()[search(key)],getElements()[search(key)].getClass());
            set(search(key), null);
        }
        return GenericTypeChangeUtil.typeConversion(element,element.getClass());
    }

    @Override
    @SuppressWarnings("unchecked")
    public boolean addAll(List<T> list) {
        if (list == null || list.size() == 0){
            return false;
        }
        Object[] source = getElements();
        Object [] tar = new Object[this.getLength() + list.size()];
        int tarLength = tar.length;
        if (this.length >= 0) {
            System.arraycopy(source, 0, tar, 0, this.length);
        }
        for(int i = this.length-1; i < tarLength; i++){
            tar[i] = list.get(tarLength-i);
        }
        SequenceTable<T> ns = new SequenceTable<T>((T[])tar,tarLength);
        setElements(ns.getElements());
        setLength(ns.length);
        return true;
    }

    private boolean isOutOfBounds(int i){
        return i < INIT_LENGTH || i > length - 1;
    }
}

工具类源码:

/**
 * Generic type change util
 *
 * @author Sharry
 * @since 2023/9/21
 */
public class GenericTypeChangeUtil {
    @SuppressWarnings("unchecked")
    public static <T> T typeConversion(Object o, Class<?> tClass){
        return (T) tClass.cast(o);
    }
}

分别对顺序表、工具类进行Mocktio + Junit 5进行测试:

依赖:

        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.8.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-inline</artifactId>
            <version>4.3.1</version>
            <scope>test</scope>
        </dependency>

顺序表测试:

	@Test
    void getElements() {
        Mockito.when(sequenceTable.getElements()).thenCallRealMethod();
        log.info("Forward value:{}", Arrays.toString(sequenceTable.getElements()));
        Object[] elements = sequenceTable.getElements();
        Assertions.assertEquals(elements,sequenceTable.getElements());
    }
// 其余测试代码略.....

工具类测试:

@Test
    void typeConversion() {
        try(MockedStatic<GenericTypeChangeUtilTest> testUtil = Mockito.mockStatic(GenericTypeChangeUtilTest.class)){
            Assertions.assertEquals(1, (Integer) GenericTypeChangeUtil.typeConversion(1,Integer.class));
        }
    }

由于日常工作时测试是个大佬,因此我们普通马仔在日常开发中若是交期紧,就会在开发完后Swagger文档稍微测试一下就给测试了,没有顾及太多单元测试,上面的测试也只是照着参考教程写的。趁此机会就补补单元测试的概念吧:

为什么要Mockito + Junit

  • Junit : 最常见的Java单元测试工具之一。一般情况下,Junit已集成在一些工具或框架中。如IDEA就自带了Junit,可以用IDEA的Generate生成对应测试类。
  • Mockito:使用Mock对象的方式进行测试。使用Mock可以让我们在相对独立的测试环境,使用专用的对象进行模拟,可以进一步规范对象的动作,捕捉对象的行为。简单来说就是更独立,不用去动实际要动的对象。

常见概念

  • 断言:assert。assert具体在代码的体现就是Junit提供的方法了,其作用为:当断言里的结果是我们预期的结果时,测试通过;否则IDE会报红。具体assert的用法会根据Junit的版本不同而有差异,使用示例在上面的代码中。

  • 测试类常用注解:

    • @BeforeEach : 准备工作。在上述例子中的体现就是对Mock进行初始化。
    • @AfterEach : 结束工作。
  • Mokito常用注解与方法

    • @Spy : 使用真实的对象(有些对象难以Mock)
    • @Mock : 模拟对象
    • MockitoAnnotations.openMocks(class) 配合初始化注解使用,建议放在@BefoeEach方法上
    • Mockito.when().thenCallRealMethod() 方法,使用执行该方法的返回值,而不是自己定义的thenReturn值
    • Mokito.when().thenThrow()方法 ,抛出异常
    • @InjectMocks :将@Mock的对象注入到该注解修饰的对象中
威联通改装飞牛fnOS全攻略:从刷机到Docker影视部署 NAS系统是家庭数字存储的核心,x86架构的威联通设备凭借通用引导和驱动支持,成为改装替代系统的理想平台。飞牛fnOS作为基于Debian的国产NAS系统,以简洁UI、内置Docker和影视墙以及硬件转码能力,吸引了大量玩家。通过U盘引导安装、BIOS调整、系统盘SSD部署,可实现系统切换;原机械硬盘可挂载为存储池,配合Docker部署下载、远程访问等容器,影视中心自动削刮海报墙,硬件转码保障4K播放。改装过程需注意引导失败、硬盘识别、核显驱动等问题。这套方案能让老旧威联通焕发新生,兼顾易用性与扩展性。本文 阅读详情

相关推荐

数据中心GPU芯片性能参数速查表(Nvidia+国产算力卡)

本文提供了一份数据中心GPU芯片性能参数速查表,涵盖Nvidia与国产算力卡两大阵营。文章详细解读了算力、显存、互连技术及功耗等关键性能指标,并对比了A100、H100、昇腾910B等主流型号,旨在帮助用户根据AI训练、推理等实际场景,做出高效的硬件选型与成本评估决策。

a0b1c2d3的专栏 835

解决 泛型类型转换出现Unchecked cast: ‘java.lang.Object‘ to ‘T‘怎么解决

在进行类型转换时,如果不确定转换后的类型,就会出现Unchecked cast: ‘java.lang.Object’ to 'T’的警告信息。为了避免这种警告信息,可以使用泛型边界进行限制。自定义工具类,编写公共方法,根据不同日期类型,将毫秒值转换对应的日期类型。如果要将一个Object类型的变量转换为指定的泛型类型T。类型的参数来确定泛型类型,并且使用。类型强制转换泛型T,警告提示。方法进行强制类型转换,避免了。

极客鼠之家 2458

CAT24C16 EEPROM的I²C页写与页读底层实现

I²C是一种广泛应用于嵌入式系统的双线同步串行通信协议,其核心在于严格的时序控制、地址寻址机制与主从应答逻辑。理解I²C总线物理层(上拉电阻、SCL/SDA电气特性)、协议层(START/STOP、ACK/NACK、7位地址格式)及外设寄存器操作(如SR1状态标志、CCR时钟分频),是实现可靠通信的基础。在实际工程中,EEPROM类器件(如CAT24C16)因其非易失性、页缓冲区结构和写保护(WP)功能,成为数据持久化关键载体;其16字节页写约束、内部写周期(5–10ms)与地址指针自动递增等特性,直接决定

weixin_42591413的博客 388

Unchecked cast: java.lang.Object to java.util.List问题的解决

包含5种解决方式

lydms的博客 6万+

目标检测数据集 第059期-基于yolo标注格式的水果李子检测数据集(含免费分享)

李子作为中国三大水果之一,种植历史超 3000 年,在市场中占据重要地位。传统李子种植、施肥、采摘依赖大量人力,存在资源浪费、产量估算不准、采摘时机难把控等问题。此前,农业领域缺乏针对 “未成熟李子” 的专用数据集,现有水果检测数据集多聚焦于成熟果实(如苹果、柑橘),且未覆盖李子种植的复杂自然场景。在使用该数据集进行学术研究时,应遵守相关的学术规范,引用该数据集的来源,尊重数据集创作者的劳动成果。,用于训练改进型模型,解决李子精准检测的核心痛点。

深度学习算法工程师,专注于前沿算法研究与实战应用。在这里,我将分享深度学习领域的实战经验、优质数据集资源以及最新论文解读与精度分析,旨在与广大技术爱好者共同探索人工智能的奥秘,助力技术成长与创新。 772

Windows 11 安装 JDK 25:下载、安装、配置环境变量、验证

本文详细介绍了在 Windows 11 系统上安装 JDK 25 的完整流程,包括从 Oracle 官网下载压缩包、解压至自定义目录、配置 JAVA_HOME 与 Path 环境变量,并验证安装是否成功。文章推荐使用 ZIP 压缩包而非 EXE 安装程序,以实现绿色便携、多版本共存和灵活管理。最后通过一个使用 Java 25 新特性的示例程序,验证 JDK 的编译与运行环境。

寒水馨 · 轻量级技术文档 · hanshuixin.org 7661

IDEA Object强转提示:Unchecked cast: 'java.lang.Object' to 'T'

idea中使用强转提示:Unchecked cast: 'java.lang.Object' to 'T',网上很多都是加什么注解取消提示的。 解决办法: import com.fasterxml.jackson.databind.ObjectMapper; public static <T> T objParse(Class<T> returnClas...

su330494482的博客 1万+

AIGC时代的必备技能:提示词工程(Prompt Engineering)全面指南

本文主要介绍了AIGC时代的重要技能——提示词工程(Prompt Engineering)。文章首先定义了提示词的概念,强调其作为人类与AI沟通桥梁的重要性,并详细阐述了提示词的功能特性,包括输入、大模型处理和输出三个环节。接着,文章探讨了提示工程的重要性,如提高输出质量、节省资源和时间等。随后,文章深入分析了提示词的基本构成要素,包括指令、上下文、输入数据和输出指示符,并提出了提示词的五大基本原则:清晰性与具体性、提供充足的上下文、明确任务与目标、考虑受众和迭代思维。最后,文章介绍了提示词的七大常见技巧

weixin_43178406的博客 27万+

泛型——尽量消除非受检警告

有些警告源于我们的设计, 无法轻易消除,比如我们原始信息就是多种,这时候 我们知道这个数据就是这个样子, 那我们只能使用强转来处理类型。为了处理这种警告, 我们需要使用注解 @SuppressWarnings("unchecked")正确处理掉这些警告之后, 我们可以保证至少泛型的类型转换不会出错, 如以下的场景就可以避免。这时候获取的时候就会报 unchecked cast (非受检强制转换警告)比如我们设计一个缓存, 为了方便使用, 我们允许存储各种格式。关于 @SuppressWarnings。

GSON的博客 1795

【推荐100个unity插件】对话系统插件——YarnSpinner-Unity插件

Yarn Spinner是一款专为游戏对话设计的脚本语言,适用于Unity等引擎。本文介绍了在Unity中安装和使用Yarn Spinner的完整流程:首先通过Package Manager添加仓库并安装插件;然后创建Yarn Script和Project文件,配置对话系统;接着编写Yarn脚本定义对话内容,并展示运行效果;最后讲解了按键控制和多语言本地化设置。该工具采用类似剧本的简洁格式,支持分支对话、条件逻辑等功能,能有效提升游戏叙事的开发效率。

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 2212

初识 QML

QML 是一种声明性语言,允许根据用户界面的可视组件以及它们如何相互交互和相互关联来描述用户界面。QML 是一种高度可读的语言,旨在使组件能够以动态方式互连,并且允许组件在用户界面中轻松重复使用和自定义。 使用 Qt Quick,开发人员可以轻松地在 QML 中构建流体动画用户界面,并且可以选择将这些用户界面连接到任何后端 C++ 库。

青春不老,奋斗不止! 1万+

优雅消除 Unchecked cast 提醒

优雅消除 Unchecked cast 提醒的方法

成长记录——编程、跑步、阅读、未来…… 4127

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Java - Unchecked Cast Warning 的背景,原因以及解决方法

背景 在使用 Spring Boot 的时候,在 controller 里获取一个 payload 对象,接着从 payload 对象里取得我们想要的 list 。 // Controller public ResponseEntity<Object> method(@RequestBody JSONObject payload) { List<?> list = pay...

互相学习 1万+

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

将Object转换成List

java中如果需要将一个object转成list,大部分人会直接使用强制类型转换:(List<String>) obj这样。这样强制转换编译会提示Unchecked cast: 'java.lang.Object' to 'java.util.List<java.lang.String>',编译器的意思该强制类型转换并未做类型校验,强制转换并不安全,可能会抛出异常导致程序崩...

ptsx0607的专栏 17万+

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

解决Java中的“Unchecked cast: java.lang.Object to java.util.List”问题

本博客将重点讨论在Java中遇到的“问题,提供了解决这个问题的方法和技巧。在Java中,遇到“”问题时,我们需要注意进行类型检查、合理使用泛型以及避免原始类型的使用。通过这些方法,可以有效地解决类型转换异常,提高代码的稳定性和可维护性。

沉淀所学,分享所思,让热爱与成长同行。商务记录AI实战经验,助力开发者快速成长。 热爱AI,希望做出有影响力的技术成果。 技术点亮生活,分享连接价值与机会。 专注AI落地实战,陪你走好技术每一步。 2万+

idea警告:Unchecked cast: ‘java.lang.Object‘ to ‘java.util.List

出现原因,实际应用时map集合中存在多个键值对,而由于每个键对应的值为不同类型,当存在一个值的类型为List时,在接收时做强制转换会出现此警告。 为了防止这个问题可以在方法上添加 @SuppressWarnings(“unchecked”)来消除警告,但是这只是忽略了问题,其实问题依然存在,彻底解决的方式是使用jackson来类型转换: List<Integer> integerList= new ObjectMapper().convertValue(map.get("roleIdList")

二十一克阳光!的博客 6303

泛型强制转换报错 Unchecked cast: ‘java.lang.XXX‘ to ‘T‘

在需要强制转换为泛型的时候,编辑器会提示警告,可以使用 Class.cast() 进行处理

assember的博客 1万+

已解决Java中的“Unchecked cast: java.lang.Object to java.util.List”问题,亲测有效!!!已解决

在Java中,当你尝试将一个Object类型的对象强制转换为List类型,而编译器无法确保这种转换的安全性时,就会遇到“Unchecked cast: java.lang.Object to java.util.List”的警告。这通常发生在泛型被擦除的情况下,或者当你从原始类型(没有使用泛型)的集合或方法中获取对象时。 解决这个问题的正确方法取决于你的具体使用场景,但通常涉及以下几个步骤:

PythonAigc的博客 2713

Object转换list时的错误及解决方法

将Object转化成list.......这样强制转换编译会提示Unchecked cast: 'java.lang.Object' to 'java.util.List,编译器的意思该强制类型转换并未做类型校验,强制转换并不安全,可能会抛出异常导致程序崩溃。

m0_56556747的博客 2310

泛型类型转换出现Unchecked cast: ‘java.lang.Object‘ to ‘T‘错误解决

【代码】 泛型类型转换出现Unchecked cast: ‘java.lang.Object‘ to ‘T‘错误解决。

weixin_44917365的博客 620

idea警告:Unchecked cast: 'java.lang.Object' to 'java.util.List<java>'

1. 出现原因,实际应用时map集合中存在多个键值对,而由于每个键对应的值为不同类型,当存在一个值的类型为List时,在接收时做强制转换会出现此警告 2. 出错代码举例: Map<String,Object> repeatMap = checkAndRemoveRepeatRecords(dataList); ...

Jalen备忘录 5万+

泛型(7):擦除的补偿

正如我们看到的,擦除丢失了在泛型代码中执行某些操作的能力。偶尔可以绕过这些问题来编程,但是有时必须通过引入类型标签来对擦除进行补偿。这意味着你需要显式地传递你的类型的Class对象,以便你可以在类型表达式中使用它。例如,在前面示例中对使用instanceof的尝试最终失败了,因为其类型信息已经被擦除了。编译器将确保类型标签可以匹配泛型参数。

游王子og的博客 879

Unchecked cast: ‘java. lang. Object‘ to ‘java. util. Map<java. lang. String,java. lang. Object>‘ 解决

代码中使用Feign请求目标接口,feign返回的数据的getData部分是一个Object对象, 需要转换成JsonObject才能获取里面的值,直接强制转换会有Unchecked cast的警告,很麻烦。

优秀的程序员不应该是CRUD 664
上一篇: 【计算机基础】数据结构与算法基本概念
下一篇: 【杂谈】生活记录:程序猿的养生保健颈椎篇
CoderSharry
博客等级 码龄4年 515粉丝 69原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值