新东方在线网上课程,深圳seo公司助力网络营销飞跃,网络营销公司名称,杭州seo代理公司6.Java接口和抽象类的区别#xff1f;
不同点
1.接口在Java8之前不能写方法实现逻辑#xff0c;Java8及以后的版本#xff0c;可以用default关键字写方法的实现。
2.接口中方法都是public的#xff0c;public可以省略#xff0c;而抽象类没有这个限制。
3.接口用inter…6.Java接口和抽象类的区别
不同点
1.接口在Java8之前不能写方法实现逻辑Java8及以后的版本可以用default关键字写方法的实现。
2.接口中方法都是public的public可以省略而抽象类没有这个限制。
3.接口用interface关键字抽象类用abstract class来声明。
相同点
接口和抽象类都不能直接new。
实战总结
接口用于制定规范而抽象类用于代码的复用比如模板方法模式。
实际开发中我们用接口来制定规范直接参与上层业务Controller代码的编写然后具体的实现放到业务层ServiceImpl如果实现类有很多相同的逻辑就可以考虑封装为一个抽象类。
举一个例子Excel导入我们可以封装一个导入接口
public interface ImportService {/*** Excel导入* param file 上传的excel文件* return*/ResultImportResultDto importData(MultipartFile file);}importData 要求输入一个file文件返回导入的结果。
具体使用是在controller层
public ResultImportResultDto imp(RequestParam(file) MultipartFile file) {return userImportService.importData(file);}userImportService 就是具体的实现类是ImportService接口的业务实现。
又因为Excel导入通常都需要这么几个步骤解析文件 - 校验数据 - 保存数据 - 返回导入结果。
因此我们可以再单独封装一个抽象类。
public abstract class AbstractImportServiceT implements ImportService {OverrideTransactional(rollbackFor Throwable.class)public ResultImportResultDto importData(MultipartFile file) {checkFileType(file.getOriginalFilename());ListT dataList parseData(file);ImportResultDto resultDTO checkData(dataList);if (resultDTO null || CollectionUtils.isEmpty(resultDTO.getErrorList())) {this.saveData(dataList);return Result.success();}return Result.fail(ResultEnum.SYSTEM_OP_ERROR.getCode(), 导入失败, resultDTO);}/*** 解析文件中的数据** param file 文件* return*/protected abstract ListT parseData(MultipartFile file);/*** 校验数据** param dataList 数据* return*/protected abstract ImportResultDto checkData(ListT dataList);/*** 处理数据** param dataList 数据*/protected abstract void saveData(ListT dataList);/*** 校验文件类型*/private static void checkFileType(String fileName) {if (StringUtils.isNotBlank(fileName) fileName.contains(.)) {String suffix fileName.substring(fileName.lastIndexOf(.)).toLowerCase();if (StringUtils.isNotBlank(suffix) Arrays.asList(.xls, .xlsx).contains(suffix)) {return;}}throw new BusinessInfoException(ResultEnum.SYSTEM_INNER_ERROR, 只支持excel文件导入请检查);}
}这就是一个典型的模板方法模式因为这个抽象类已经实现了接口所以真正的实现类就不需要重复去实现了只需要继承这个抽象类即可。
7.Java中有了基本类型为什么还需要包装类
先说渊源Java毕竟是面向对象的语言很多地方都需要用到象比如集合类中是无法塞进基本类型的。 某杠精你胡扯我塞入int类型的压根不报错
public static void main(String[] args) {ListInteger numbers new ArrayListInteger();numbers.add(1);
}这是因为从JDK5开始就支持了自动拆装箱系统所以并不是集合可以装进基本类型而是系统帮我们自动装箱了。
自动装箱都是通过包装类的 valueof()方法来实现的自动折箱都是通过包装类对象的xxxValue()来实现的。
已int为例
Integer a 1; // 自动装箱
int b a; // 自动拆箱相当于
Integer a Integer.valueOf(1);
int b a.intValue(); 避坑指南
1.注意空指针
有的时候我们会直接用包装类去参与四则运算这个时候要注意包装类对象不能是null因为自动拆箱会调用xxxValue()方法就会有报空指针的风险。
public class Test {public static void main(String[] args) {Integer a getCount();int b a 10; }private static Integer getCount() {// 因为某种原因返回了nullreturn null;}
}恭喜你喜提 NullPointerException一份。 2.Entity中一定要用包装类
java老鸟都知道Entity中一定不能用基本类型因为基本类型有默认初始值比如int类型默认就是0如果结合Mybatis会不小心把这个默认值误更新到数据库而用Integer则没问题因为对象默认为nullmybatis默认的策略就是不更新Null值是安全的。
8.接口的返回值一定要用包装类
我们写接口给外部调用按理说就必须要是一个明确的值如果你接口返回boolean默认是false这个false我们也不知道究竟是计算后得到的还是基本类型默认的这就有二义性。
3.为什么用float会有精度丢失的问题
要解答这个问题我们得知道计算机中用32bit来标识一个浮点数即将一个数字转换为一个32位的二进制数。比如10就是1010。表达整数没问题但是并非所有小数都能用二进制表示我们知道10进制转二进制用的是辗转相除法除以2那总有除不尽的时候吧
所以即便float有32bit也是一个近似值。double也是一样的只是精度更高了有64bit。
对于金额的计算Java提供了BigDecimal来表示和运算。
9.请说说String、StringBuilder和StringBuffer的区别
可变性 String是不可变的StringBuilder和StringBuffer是可变的。
为什么String要设计为不可变的呢
首先String使用太频繁了JVM单独开辟一块区域用作字符串缓存池节省内存的开支。又因为String不可变所以hashCode也不变方便命中缓存提高效率我们用HashMap的时候你敢说自己不用String作为Key吗一样的道理。
安全性 StringBuffer是线程安全的而StringBuilder是非线程安全的。
StringBuffer 和 StringBuilder如何取舍
StringBuilder是非线程安全的也就意味着效率更高在方法体里面本来也不会涉及到线程安全问题拼接较多的话值得使用。
尽量不要使用 来拼接字符串因为 虽然编译时也会转成StringBuilder但每次都会new一个反而影响性能。
10.什么是泛型
泛型是JDK5引入的一种新特性泛型包括泛型类和泛型方法目的是保证数据类型的安全常与集合类一起使用。
1.方便:可以提高代码的复用性。
以List接口为例我们可以将String、Integer等类型放入List中如不用泛型存放String类型要写一个List接口存放Integer要写另外一个List接口泛型可以很好的解决这个问题。
ArrayList源码: 2.安全
在泛型出之前通过Object实现的类型转换需要在运行时检查如果类型转换出错程序直接GG可能会带来毁灭性打击。。而泛型的作用就是在编译时做类型检查这无疑增加程序的安全性。
3.什么是泛型擦除
泛型擦除是指在编译过程中泛型会被擦除最终只会得到同一份字节码。因此泛型主要的功能就是在编译时确保数据类型的正确性防止把问题留到运行时。