当前位置: 首页 > news >正文

默认生成的接口实现方法体的问题

随着集成开发环境越来越强大,编程开发工作也变得越来越高效,很多的代码都不需要逐字输入,可以利用代码生成和自动补全来辅助开发。但是这样的便利也可能引起一些疏忽,本文就Java开发中默认生成的接口实现方法来谈谈以前遇到的问题。

平时做Java开发的时候,我们经常需要去实现他人定义的接口,这个时候通常写完implements xxxx的代码后,使用开发工具来生成缺少的空方法,例如下面这样:

class ATask implements Runnable {@Overridepublic void run() {}
}

这么做可以让我们节省一些时间。上面的例子是最简单的情况,实际开发中情况要复杂的多。下面来看看复杂情况下可能出现的问题

问题一:方法很多并包含很多空实现

有时候用第三方库的时候,经常看到回调的接口中包含5个以上的方法,而这些方法并不是都需要用到,那么就会出现很多的空方法体,比如像Android播放器ExoPlayerEventListener就包含了7个方法:

public interface EventListener {void onTimelineChanged(Timeline var1, Object var2);void onTracksChanged(TrackGroupArray var1, TrackSelectionArray var2);void onLoadingChanged(boolean var1);void onPlayerStateChanged(boolean var1, int var2);void onPlayerError(ExoPlaybackException var1);void onPositionDiscontinuity();void onPlaybackParametersChanged(PlaybackParameters var1);
}

但这些方法我们并不是都要用到,所以可能在相关功能的实现中存在很多空方法体,像这样:

@Override
public void onTimelineChanged(Timeline timeline, Object o) {}@Override
public void onTracksChanged(TrackGroupArray trackGroupArray, TrackSelectionArray trackSelectionArray) {}@Override
public void onLoadingChanged(boolean b) {}@Override
public void onPlayerStateChanged(boolean b, int i) {}@Override
public void onPlayerError(ExoPlaybackException e) {}@Override
public void onPositionDiscontinuity() {}@Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {}

不仅占据大量篇幅, 而且还可能引起歧义:这些方法到底是可忽略的,还是忘记实现的,又或是当时可忽略,将来需要实现的?

针对可忽略的,我们可以像AnimationAdapterListener那样,定义一个适配器接口,将那些忽略的方法放在这样的Adapter中:

public class AnimationAdapterListener implements Animation.AnimationListener {@Overridepublic void onAnimationStart(Animation animation) {}@Overridepublic void onAnimationEnd(Animation animation) {}@Overridepublic void onAnimationRepeat(Animation animation) {}
}

然后原本使用AnimationListener的地方,就用AnimationAdapterListener,然后将重写关注的方法即可,这样就不会出现大量的空方法

如果这些方法都不是可忽略的,还是建议在默认生成的方法体中通过注释、日志、甚至抛出异常等方式填充内容,起到一个补充说明的作用,以免将来看着空方法体一头雾水。当然如果IDE允许,尽量还是生成带有信息的方法体,例如下面这样:

class ATask implements Runnable {@Overridepublic void run() {//TODO not implement}
}

问题二:生成的方法体的默认返回值问题

当接口声明的方法带有返回值的时候,IDE辅助生成的空方法体可能包含默认返回值,例如,接口返回值是boolean时,默认返回false

class Obj implements XXXInter{@Overridepublic boolean isXXX(){return false;}
}

或许在最初开发的时候,这种情况是可以忽略的,但是过段时间或者经历多人维护以后,就没法区分是“设计如此”还是“无意为之”的结果。对于熟悉的接口不会造成太大问题,如果是不太熟悉的第三方库的接口,那就可能因为疏忽而导致难以预料的情况。

针对有返回值的方法,还是建议默认实现采用抛出异常的方式:

class Obj implements XXXInter{@Overridepublic boolean isXXX(){throw new RuntimeException("not implement");}
}

只有在明确功能的情况下,才返回具体的值。

问题三:实现不同接口的同名方法

最后一个问题非常少见,但是一旦出现,就可能导致比较诡异的bug。

实际开发中一个类可能会实现3个甚至5个接口,如果这些接口包含方法签名相同的方法,那么IDE辅助生成的方法实现中同签名方法只会有一个方法体,例如:

interface A {void testA();boolean isValid();
}interface B {void testB();boolean isValid();
}class ATask implements A,B {@Overridepublic void testA() {}@Overridepublic void testB() {}@Overridepublic boolean isValid() {return false;}
}

这里接口AB都包含isValid方法声明,但是ATask中只有一个isValid实现,如果AB中该方法的意义不同,那么情况又比较麻烦了。在开发阶段就发现,可以通过内部类或辅助类的方式来分离两个接口的实现;但如果已经是在老项目中出现这样的代码,那么就可能在不知道这个方法同时属于两个接口的情况下去改动进而出现“写bug”的行为。

对于这个问题,可以按照“单一职责”的思想,一个类尽量不要实现太多接口,保持其职责的单一。如果某些特殊情况真的需要一个方法同时实现两个接口的情况,还是建议补充注释来强调下。

相关文章:

默认生成的接口实现方法体的问题

随着集成开发环境越来越强大,编程开发工作也变得越来越高效,很多的代码都不需要逐字输入,可以利用代码生成和自动补全来辅助开发。但是这样的便利也可能引起一些疏忽,本文就Java开发中默认生成的接口实现方法来谈谈以前遇到的问题…...

【OJ】十级龙王间的决斗

📚Description: 在《驯龙高手2》,最精彩的高潮出现在两只阿尔法决斗的时候。 驯龙高手中的十星龙王又称喷冰龙,有且只有两只,是最大型的龙,所有其他龙都要膜拜它(当然,幼龙除外)&…...

java 自定义注解

文章目录前言Annotation包自定义注解自定义注解示例参考文章:java 自定义注解 用处_java注解和自定义注解的简单使用参考文章:java中自定义注解的作用和写法前言 在使用Spring Boot的时候,大量使用注解的语法去替代XML配置文件,十…...

产品经理知识体系:2.如何进行商业需求分析?

商业需求分析 思考 笔记 用户细分: 核心用户、用户分级 用户关系: 如何维护用户关系、维护等成本 关系和商业模式的整合 核心价值: 解决什么问题,满足什么需求,最终带给用户什么价值 渠道通道: 如何触达…...

EditPlus正则表达式替换字符串详解

正则表达式是一个查询的字符串,它包含一般的字符和一些特殊的字符,特殊字符可以扩展查找字符串的能力,正则表达式在查找和替换字符串的作用不可忽视,它能很好提高工作效率。EditPlus的查找,替换,文件中查找…...

Go基础-环境安装

文章目录1 Go?Golang?2 下载Go3 windows安装4 测试是否成功1 Go?Golang? Go也称为Golang,是Google开发的一个开源的编译型的静态语言。 Golang的主要关注点是高可用、高并发和高扩展性,Go语言定位是系统级编程语言,对web程序具有很好的支…...

《NFL橄榄球》:纽约巨人·橄榄1号位

纽约巨人(New York Giants)是美国全国橄榄球联盟在新泽西州东卢瑟福的一支球队。巨人是在1925年作为五个成员之一加入国家美式橄榄球联盟。 在2018年时,球队市值为33亿美元,在世界前50名球队中并列第8名,同时在NFL高居…...

2023/02/18 ES6数组的解读

1 扩展运算符 扩展运算符(spread)是三个点(…). 它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列. console.log(...[1, 2, 3]) // 1 2 3console.log(1, ...[2, 3, 4], 5) // 1 2 3 4 5该运算符主要用于…...

Ubuntu 20 安装包下载(清华镜像)

Ubuntu 20 安装包下载在国内推荐使用清华大学镜像 清华镜像地址:https://mirrors.tuna.tsinghua.edu.cn/ 在搜索框中输入Ubuntu,然后点击Ubuntu -release,这里面有近几年的Ubuntu镜像 点击你想下载的版本,我选择的是20.0413点击…...

华为OD机试 - 机器人走迷宫(JS)

机器人走迷宫 题目 房间有X*Y的方格组成,例如下图为6*4的大小。每一个放个以坐标(x,y)描述。 机器人固定从方格(0,0)出发,只能向东或者向北前进, 出口固定为房间的最东北角,如下图的方格(5,3)。 用例保证机器人可以从入口走到出…...

字节二面:10Wqps超高流量系统,如何设计?

超高流量系统设计思路 前言 在40岁老架构师 尼恩的**读者交流群(50)**中,大流量、高并发的面试题是一个非常、非常高频的交流话题。最近,有小伙伴面试字节时,遇到一个面试题: 10Wqps超高流量系统,该如何设计&#xf…...

基于springboot+html汽车维修系统汽车维修系统的设计与实现

基于springboothtml汽车维修系统汽车维修系统的设计与实现 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取项目下载方式&#x1…...

营销狂人杜国楹的两大顶级思维

“营销狂人”小罐茶 杜国楹两大顶级思维 1.一定要有【参照物思维】 2.一定要有【终局思维】 趣讲大白话:大牛的思考就是不同 *********** 杜国楹对茶行业思考 1.参照咖啡、酒的发展路径 2.中国茶工业化,品牌化是唯一壮大之路 3.龙头企业必须全品 没有参照物思维就没…...

面试题-前端开发JavaScript篇下(答案超详细)

文章目录 实现一个 once 函数,传入函数参数只执行一次将原生的 ajax 封装成 promisJS 监听对象属性的改变如何实现一个私有变量,用 getName 方法可以访问,不能直接访问==和===、以及 Object.is 的区别setTimeout、setInterval 和 requestAnimationFrame 之间的区别实现一个两…...

Android 9.0 修改Recovery字体图片的大小(正在清理)文字大小

1.概述 在9.0的系统产品定制化开发中,在系统中recovery功能也是非常重要的功能,所以说在进行recovery的时候,正在清理的 字体显示的有些小了,所以产品需求要求改大recovery的字体大小,所以这就需要在recovery页面看下字体大小的显示逻辑然后修改字体的显示大小,主要功能修…...

操作系统 五(文件系统)

一 文件定义:文件是指由创建者所定义的,具有文件名的一组相关元素的集合,可分为有结构文件和无结构文件两类。在有结构文件中,文件由若干个相关记录组成。而无结构文件则被看成一个字节流。文件在文件系统中是一个最大的数据单位&…...

华为OD机试 - 人数最多的站点(JS)

人数最多的站点 题目 公园园区提供小火车单向通行,从园区站点编号最小到最大, 通行如1~2~3~4~1万,然后供员工在各个办公园区穿梭, 通过对公司N个员工调研统计到每个员工的坐车区间,包含前后站点, 请设计一个程序计算出小火车在哪个园区站点时人数最多。 输入 输入的第…...

Mr. Cappuccino的第41杯咖啡——Kubernetes之Pod调度策略

Kubernetes之Pod调度策略Pod的4种调度策略定向调度nodeNamenodeSelector亲和性调度node亲和性硬限制软限制关系运算符pod亲和性pod反亲和性污点和容忍污点(taints)容忍(tolerations)默认情况下,Scheduler计算出一个Pod…...

Linux 磁盘挂载

目录 Linux硬盘分区 硬盘设备的文件名 /dev/sd[a-z] 硬盘分区 识别硬盘的文件名 Linux文件系统 文件系统类型 Linux如何保存文件 VFS虚拟文件系统 磁盘挂载命令 lsblk 查看系统的磁盘使用情况 fdisk 硬盘分区 mkfs 格式化文件系统 mount 挂载命令 df 显示磁盘空间…...

命名冲突问题与命名空间

一、何为命名空间&#xff1f; 首先我们运行下面代码&#xff0c; #include <stdio.h> int rand 0; int main() {printf("%d", rand);return 0; } 我们会发现该代码能够正常运行&#xff0c;没有任何问题。 但是当我们再在上面代码的基础上包含stdlib.h头…...

Java 语言特性(面试系列1)

一、面向对象编程 1. 封装&#xff08;Encapsulation&#xff09; 定义&#xff1a;将数据&#xff08;属性&#xff09;和操作数据的方法绑定在一起&#xff0c;通过访问控制符&#xff08;private、protected、public&#xff09;隐藏内部实现细节。示例&#xff1a; public …...

R语言AI模型部署方案:精准离线运行详解

R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

Qt Http Server模块功能及架构

Qt Http Server 是 Qt 6.0 中引入的一个新模块&#xff0c;它提供了一个轻量级的 HTTP 服务器实现&#xff0c;主要用于构建基于 HTTP 的应用程序和服务。 功能介绍&#xff1a; 主要功能 HTTP服务器功能&#xff1a; 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

VTK如何让部分单位不可见

最近遇到一个需求&#xff0c;需要让一个vtkDataSet中的部分单元不可见&#xff0c;查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行&#xff0c;是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示&#xff0c;主要是最后一个参数&#xff0c;透明度…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作

一、上下文切换 即使单核CPU也可以进行多线程执行代码&#xff0c;CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短&#xff0c;所以CPU会不断地切换线程执行&#xff0c;从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

高防服务器能够抵御哪些网络攻击呢?

高防服务器作为一种有着高度防御能力的服务器&#xff0c;可以帮助网站应对分布式拒绝服务攻击&#xff0c;有效识别和清理一些恶意的网络流量&#xff0c;为用户提供安全且稳定的网络环境&#xff0c;那么&#xff0c;高防服务器一般都可以抵御哪些网络攻击呢&#xff1f;下面…...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI&#xff0c;使用客户端或是内部自己搭建集成大模型的终端&#xff0c;加速与大型语言模型&#xff08;LLM&#xff09;的结合&#xff0c;同时使用检索增强生成&#xff08;Retrieval Augmented Generation &#…...

【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论

路径问题的革命性重构&#xff1a;基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中&#xff08;图1&#xff09;&#xff1a; mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...

android13 app的触摸问题定位分析流程

一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...