【Java】解决Java报错:UnsupportedOperationException

news2024/11/20 12:44:48

在这里插入图片描述

文章目录

      • 引言
      • 1. 错误详解
      • 2. 常见的出错场景
        • 2.1 不可修改的集合
        • 2.2 抽象类和接口的默认实现
        • 2.3 不支持的操作
      • 3. 解决方案
        • 3.1 使用支持操作的集合
        • 3.2 提供具体实现
        • 3.3 检查对象类型和能力
      • 4. 预防措施
        • 4.1 使用接口而非实现类
        • 4.2 编写防御性代码
        • 4.3 使用工厂方法创建集合
      • 5. 示例项目
        • 5.1 项目结构
        • 5.2 Main.java
        • 5.3 CustomList.java
        • 5.4 pom.xml
      • 6. 单元测试
        • 6.1 MainTest.java
      • 结语

引言

在Java编程中,UnsupportedOperationException 是一种常见的运行时异常,通常发生在尝试对不支持操作的对象调用某些方法时。这类错误提示为:“UnsupportedOperationException: operation is not supported”,意味着程序试图执行某个对象不支持的操作。本文将详细探讨UnsupportedOperationException的成因、解决方案以及预防措施,帮助开发者理解和避免此类问题,从而提高代码的健壮性和可靠性。

1. 错误详解

UnsupportedOperationException 是一种由 Java 运行时环境抛出的异常,表示程序试图对不支持的对象执行特定操作。该异常是 RuntimeException 的子类,不属于受检异常,因此无需显式捕获,但仍需要在代码中进行适当的处理。

2. 常见的出错场景

2.1 不可修改的集合

尝试修改由 Collections.unmodifiableListCollections.unmodifiableSetCollections.unmodifiableMap 返回的不可修改集合时,会抛出该异常。

import java.util.*;

public class Main {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
        List<String> unmodifiableList = Collections.unmodifiableList(list);
        unmodifiableList.add("D");  // 尝试修改不可修改的集合,将抛出UnsupportedOperationException
    }
}
2.2 抽象类和接口的默认实现

抽象类或接口提供的默认实现可能抛出 UnsupportedOperationException,提醒开发者需要提供具体实现。

import java.util.AbstractList;

public class Main {
    public static void main(String[] args) {
        List<String> customList = new CustomList<>();
        customList.add("A");  // 尝试调用未实现的方法,将抛出UnsupportedOperationException
    }
}

class CustomList<E> extends AbstractList<E> {
    @Override
    public E get(int index) {
        return null;
    }

    @Override
    public int size() {
        return 0;
    }
}
2.3 不支持的操作

某些类明确不支持某些操作,例如,Collections.unmodifiableList 返回的列表不支持添加或删除操作。

import java.util.*;

public class Main {
    public static void main(String[] args) {
        List<String> list = Arrays.asList("A", "B", "C");
        ListIterator<String> iterator = list.listIterator();
        iterator.remove();  // 尝试对不支持删除操作的列表进行删除,将抛出UnsupportedOperationException
    }
}

3. 解决方案

解决UnsupportedOperationException的关键在于确保对象支持所执行的操作,并在必要时提供合适的实现。

3.1 使用支持操作的集合

确保使用的集合支持所需的操作。如果需要修改集合,避免使用不可修改的集合。

import java.util.*;

public class Main {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
        list.add("D");  // 修改可修改的集合
        System.out.println(list);
    }
}
3.2 提供具体实现

在抽象类或接口中,提供具体实现以支持所需的操作,避免抛出 UnsupportedOperationException

import java.util.AbstractList;

public class Main {
    public static void main(String[] args) {
        List<String> customList = new CustomList<>();
        customList.add("A");  // 正确调用已实现的方法
        System.out.println(customList.get(0));
    }
}

class CustomList<E> extends AbstractList<E> {
    private final List<E> list = new ArrayList<>();

    @Override
    public E get(int index) {
        return list.get(index);
    }

    @Override
    public int size() {
        return list.size();
    }

    @Override
    public boolean add(E e) {
        return list.add(e);
    }
}
3.3 检查对象类型和能力

在执行操作之前,检查对象是否支持所需的操作。

import java.util.*;

public class Main {
    public static void main(String[] args) {
        List<String> list = Arrays.asList("A", "B", "C");

        if (list instanceof ArrayList) {
            list.add("D");  // 检查对象类型,确保支持添加操作
        } else {
            System.out.println("该集合不支持添加操作");
        }
    }
}

4. 预防措施

4.1 使用接口而非实现类

尽量使用接口而不是具体的实现类,以便灵活替换不同的实现类,避免 UnsupportedOperationException

import java.util.*;

public class Main {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
        modifyList(list);
    }

    public static void modifyList(List<String> list) {
        list.add("D");  // 使用接口类型,便于替换实现类
        System.out.println(list);
    }
}
4.2 编写防御性代码

在执行操作之前,编写防御性代码,以确保对象支持所需的操作。

import java.util.*;

public class Main {
    public static void main(String[] args) {
        List<String> list = Arrays.asList("A", "B", "C");

        if (isModifiable(list)) {
            list.add("D");  // 进行防御性检查,确保对象支持添加操作
        } else {
            System.out.println("该集合不支持添加操作");
        }
    }

    public static boolean isModifiable(List<?> list) {
        try {
            list.add(null);
            list.remove(list.size() - 1);
            return true;
        } catch (UnsupportedOperationException e) {
            return false;
        }
    }
}
4.3 使用工厂方法创建集合

使用工厂方法创建集合,确保返回的集合支持所需的操作。

import java.util.*;

public class Main {
    public static void main(String[] args) {
        List<String> list = createModifiableList();
        list.add("D");
        System.out.println(list);
    }

    public static List<String> createModifiableList() {
        return new ArrayList<>(Arrays.asList("A", "B", "C"));
    }
}

5. 示例项目

以下是一个示例项目,展示如何正确使用集合和方法实现,避免UnsupportedOperationException

5.1 项目结构
myproject
├── src
│   └── main
│       └── java
│           ├── Main.java
│           └── CustomList.java
└── pom.xml
5.2 Main.java
import java.util.*;

public class Main {
    public static void main(String[] args) {
        List<String> list = createModifiableList();
        list.add("D");
        System.out.println(list);

        List<String> customList = new CustomList<>();
        customList.add("A");
        System.out.println(customList.get(0));
    }

    public static List<String> createModifiableList() {
        return new ArrayList<>(Arrays.asList("A", "B", "C"));
    }
}
5.3 CustomList.java
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.List;

public class CustomList<E> extends AbstractList<E> {
    private final List<E> list = new ArrayList<>();

    @Override
    public E get(int index) {
        return list.get(index);
    }

    @Override
    public int size() {
        return list.size();
    }

    @Override
    public boolean add(E e) {
        return list.add(e);
    }
}
5.4 pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>myproject</artifactId>
    <version>1.0-SNAPSHOT</version>
</project>

6. 单元测试

编写单元测试来验证集合操作的正确性,确保代码在各种边界条件下都能正确运行。

6.1 MainTest.java
import org.junit.Test;
import java.util.List;
import static org.junit.Assert.*;

public class MainTest {
    @Test
    public void testCreateModifiableList() {
        List<String> list = Main.createModifiableList();
        assertNotNull(list);
        list.add("D");
        assertEquals(4, list.size());
   

 }

    @Test(expected = UnsupportedOperationException.class)
    public void testUnmodifiableList() {
        List<String> list = List.of("A", "B", "C");
        list.add("D");  // 尝试修改不可修改的集合,将抛出UnsupportedOperationException
    }

    @Test
    public void testCustomList() {
        CustomList<String> customList = new CustomList<>();
        customList.add("A");
        assertEquals("A", customList.get(0));
    }
}

结语

理解并有效处理UnsupportedOperationException对于编写健壮的Java程序至关重要。通过本文提供的解决方案和预防措施,开发者可以有效避免和解决这类异常,提高代码质量和可靠性。希望本文能帮助你更好地理解和处理不支持操作的问题,从而编写出更加可靠的Java应用程序。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1811253.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何快速掌握 Java 枚举类型的定义和使用场景!

Java枚举类型&#xff08;Enum&#xff09;是一种特殊的类&#xff0c;用于表示一组固定的常量。枚举类型在Java 5中引入&#xff0c;通过 enum 关键字来定义。枚举类型不仅可以使代码更具可读性&#xff0c;还能增加类型安全性并减少错误。 一、枚举类型的定义 枚举类型通过…

大模型训练的10个调试技巧

几年前&#xff0c;Andrej Karpathy 写了一篇关于训练神经网络的很棒的文章。以下是我在实施过程中遵循的一些额外事项&#xff0c;侧重于调试大型语言模型。 NSDT工具推荐&#xff1a; Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 -…

程序猿大战Python——流程控制——其他控制语句

for循环 目标&#xff1a;掌握for循环的使用。 与while循环功能类似&#xff0c;for语句也能完成反复多次的执行。 for语法&#xff1a; for 临时变量 in 序列:满足条件时&#xff0c;执行的代码1满足条件时&#xff0c;执行的代码2…… [else:当for循环正常执行结束后&#…

基于PHP+MySQL组合开发的商城小程序源码系统 附带完整的安装代码包以及搭建教程

系统概述 该商城小程序源码系统采用PHP作为后端开发语言&#xff0c;MySQL作为数据库存储引擎&#xff0c;这是一套成熟且广泛应用的技术组合&#xff0c;能够确保系统的稳定性和扩展性。前端部分则利用Vue.js等现代前端框架实现动态交互&#xff0c;保证用户体验的流畅性。 …

Java | Leetcode Java题解之第141题环形链表

题目&#xff1a; 题解&#xff1a; public class Solution {public boolean hasCycle(ListNode head) {if (head null || head.next null) {return false;}ListNode slow head;ListNode fast head.next;while (slow ! fast) {if (fast null || fast.next null) {return…

人工智能对聊天机器人训练数据的“淘金热”可能会耗尽人类编写的文本

人工智能对聊天机器人训练数据的“淘金热”可能会耗尽人类编写的文本 像ChatGPT这样的人工智能系统可能很快就会耗尽让它们变得更聪明的东西——人们在网上写下和分享的数万亿字。 Epoch AI研究集团发布的一项新研究预计&#xff0c;科技公司将在大约十年之交——2026年至203…

SpringBoot + Maven

文章目录 1、Maven2、SpringBoot3、二者之间的联系4、项目的创建 在创建项目之前&#xff0c;肯定要知道他们之间的区别 1、Maven maven是一个跨平台的项目管理工具。它是Apache的一个开源项目&#xff0c;主要服务于基于Java平台的项目构建、依赖管理和项目信息管理。 比如说…

cordic IP核中,sin and cos的使用

参考视频&#xff1a;FPGA IP之CORDIC_哔哩哔哩_bilibili FPGA IP之CORDIC使用与仿真_哔哩哔哩_bilibili 一、参数说明 functional selection rotate是旋转&#xff0c;sin and cos是计算这两个三角函数&#xff0c;sinh和cosh是计算双曲正弦和双曲余弦 phase format 对于…

Databricks超10亿美元收购Tabular;Zilliz 推出 Milvus Lite ; 腾讯云支持Redis 7.0

重要更新 1. Databricks超10亿美元收购Tabular&#xff0c;Databricks将增强 Delta Lake 和 Iceberg 社区合作&#xff0c;以实现 Lakehouse 底层格式的开放与兼容([1] [2])。 2. Zilliz 推出 Milvus Lite 轻量级向量数据库&#xff0c;支持本地运行&#xff1b;Milvus Lite 复…

【Go语言】面向对象编程(一):类的定义、初始化和成员方法

面向对象编程&#xff08;一&#xff09;&#xff1a;类的定义、初始化和成员方法 1 类的定义和初始化 Go 语言的面向对象编程没有 class 、 extends 、implements 之类的关键字和相应的概念&#xff0c;而是借助结构体来实现类的声明&#xff0c;如下是定义一个学生类的方法…

2024年【危险化学品经营单位主要负责人】免费试题及危险化学品经营单位主要负责人证考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 危险化学品经营单位主要负责人免费试题根据新危险化学品经营单位主要负责人考试大纲要求&#xff0c;安全生产模拟考试一点通将危险化学品经营单位主要负责人模拟考试试题进行汇编&#xff0c;组成一套危险化学品经营…

镜舟科技与喆塔科技签署战略合作协议,共拓工业领域数据应用

近日&#xff0c;镜舟科技与喆塔科技正式签署战略合作协议&#xff0c;旨在通过双方的深度合作&#xff0c;共同推动工业领域企业级数据分析与智能制造的融合创新&#xff0c;携手为行业客户提供更加精准、高效的数据驱动解决方案。 镜舟科技 CEO 孙文现与喆塔科技 CEO 赵文政出…

12.文件

知识点一&#xff1a;文件的存取过程 缓冲区的目的:提高存储效率磁盘使用寿命 知识点二&#xff1a;磁盘文件分类 物理上所有的磁盘文件都是二进制存储&#xff0c;以字节为单位顺序存储 逻辑上的文件分类: 文本文件&#xff1a;基于字符编码的文件&#xff0c;如ASCII、UNICO…

04. fastLED像素参考(颜色设置详解)

fastLED像素参考 原文 Overview 概述 There’s two main pixel types in the library - the CRGB class and the CHSV class. CHSV objects have to be converted to CRGB objects before they can be written out. You can also write CHSV objects into the CRGB array an…

QT6 学生管理系统以及登录(QSQLITE数据库)

一、准备工具以及环境 本文采用的是QT Creator6.5.3版本&#xff0c;代码基于C语言&#xff0c;文中所用到的数据库是QSQLITE库。 因为做的是一个简单的学生管理系统&#xff0c;所以只是做到了简单的对数据库进行增删改查等操作&#xff0c;以及一个简单的登录界面。 二、U…

wgcloud可以监测交换机的哪些数据

WGCLOUD可以监测交换机的cpu&#xff0c;内存&#xff0c;温度&#xff0c;电压&#xff0c;磁盘&#xff0c;流量传输速率等数据 WGCLOUD也是基于SNMP协议来监测交换机的

进口自力式蒸汽减压阀-美国品牌

进口自力式蒸汽减压阀是一种用于蒸汽系统中&#xff0c;通过自身能量来调节和控制蒸汽压力的装置。以下是关于进口自力式蒸汽减压阀的详细回答&#xff1a; 定义与功能&#xff1a; 进口自力式蒸汽减压阀是一种无需外加能源&#xff0c;利用被调介质&#xff08;蒸汽&#xff…

每日一题——Python实现PAT乙级1104 天长地久(举一反三+思想解读+逐步优化)七千字好文

一个认为一切根源都是“自己不够强”的INTJ 个人主页&#xff1a;用哲学编程-CSDN博客专栏&#xff1a;每日一题——举一反三Python编程学习Python内置函数 Python-3.12.0文档解读 目录 初次尝试 点评 时间复杂度分析 空间复杂度分析 综合分析 我要更强 时间复杂度分…

VitePress+Docker+jenkins构建个人网站

VitePress官网 VitePress | 由 Vite 和 Vue 驱动的静态站点生成器 可以理解为一个前端脚手架:快速生成个人站点 最好先大概看一遍 快速开始 | VitePress 可以在线体验一下 安装条件 node -v 检查下node版本 在D盘创建一个文件夹 例如:VitePress 进入文件夹 cmd npm ini…

一键安全体检!亚信安全携手鼎捷软件推出企业安全体检活动 正式上线

亚信安全联合鼎捷软件股份有限公司&#xff08;以下简称“鼎捷软件”&#xff09;正式推出“一键安全体检”服务。亚信安全网络安全专家将携手鼎捷软件数据安全专家&#xff0c;围绕企业的数智安全状况&#xff0c;进行问题探索与治愈、新问题预测与预警&#xff0c;在全面筛查…