天津网站建设普斯泰,网站分为几级页面,h5网站如何建设,做ppt兼职的网站有哪些随着集成开发环境越来越强大#xff0c;编程开发工作也变得越来越高效#xff0c;很多的代码都不需要逐字输入#xff0c;可以利用代码生成和自动补全来辅助开发。但是这样的便利也可能引起一些疏忽#xff0c;本文就Java开发中默认生成的接口实现方法来谈谈以前遇到的问题…随着集成开发环境越来越强大编程开发工作也变得越来越高效很多的代码都不需要逐字输入可以利用代码生成和自动补全来辅助开发。但是这样的便利也可能引起一些疏忽本文就Java开发中默认生成的接口实现方法来谈谈以前遇到的问题。
平时做Java开发的时候我们经常需要去实现他人定义的接口这个时候通常写完implements xxxx的代码后使用开发工具来生成缺少的空方法例如下面这样
class ATask implements Runnable {Overridepublic void run() {}
}这么做可以让我们节省一些时间。上面的例子是最简单的情况实际开发中情况要复杂的多。下面来看看复杂情况下可能出现的问题
问题一方法很多并包含很多空实现
有时候用第三方库的时候经常看到回调的接口中包含5个以上的方法而这些方法并不是都需要用到那么就会出现很多的空方法体比如像Android播放器ExoPlayer的EventListener就包含了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;}
}这里接口A和B都包含isValid方法声明但是ATask中只有一个isValid实现如果A和B中该方法的意义不同那么情况又比较麻烦了。在开发阶段就发现可以通过内部类或辅助类的方式来分离两个接口的实现但如果已经是在老项目中出现这样的代码那么就可能在不知道这个方法同时属于两个接口的情况下去改动进而出现“写bug”的行为。
对于这个问题可以按照“单一职责”的思想一个类尽量不要实现太多接口保持其职责的单一。如果某些特殊情况真的需要一个方法同时实现两个接口的情况还是建议补充注释来强调下。