为什么lambda表达式无法声明throws异常,而必须要在内部捕获?

实际上这是跟重写的方法有关,比如重写Runnable的run方法,就必须在内部捕获异常:

Runnable runnable =
() -> {
synchronized (objectWaitMainClass) {
try {
objectWaitMainClass.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};

因为Runnable的run方法没有声明任何异常,所以实现了该方法的方法就无法声明任何异常,只能内部捕获

下面自定义一个接口,接口方法中声明了异常:

@FunctionalInterface
public interface ThrowException { /**
* 可能会抛出异常
*
* @throws Exception
*/
public void throwException() throws Exception;
}

用lambda表达式重写:

ThrowException throwException =
() -> {
synchronized (objectWaitMainClass) {
objectWaitMainClass.wait();
}
};

就不用lambda内部捕获,基类接口中已经声明了该异常

整个测试类:

/**
*
*
* <ul>
* <li>由于基类中的方法没有声明异常比如Runnable#run方法,所以重写该run方法就不能声明异常,比如要内部捕获;
* <li>如果基类中方法声明了异常,那么重写该方法就可以不再内部捕获,比如本类中的内部接口中的方法{@link ThrowException#throwException()}
* </ul>
*
* @see ThrowException#throwException()
* @see Runnable#run()
* @author rhyme
* @date 2020/5/30 12:02
*/
public class LambdaExceptionMain {
public static void main(String[] args) throws InterruptedException { Class<LambdaExceptionMain> objectWaitMainClass = LambdaExceptionMain.class;
Runnable runnable =
() -> {
synchronized (objectWaitMainClass) {
try {
objectWaitMainClass.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}; ThrowException throwException =
() -> {
synchronized (objectWaitMainClass) {
objectWaitMainClass.wait();
}
};
} /**
* 自定义一个函数式接口,方法中声明了异常
*/
@FunctionalInterface
public interface ThrowException { /**
* 可能会<b>抛出异常</b>的函数式接口中的方法
*
* @throws Exception
*/
public void throwException() throws Exception;
}

CRLF,CR,LF的区别和联系

windows系统文件格式默认换行"是\r\n",即CRLF;

UNIX/Linux系统文件格式默认换行是"\n",即LF;

MacOS系统文件格式默认换行由"\r",即CR。

所以比如在windows上,用Notepad++打开一个文件,想要匹配里面的换行,就要用"\r\n"匹配。

数据库字段最好不要用基本类型

比如 一个字段设定为@Column(name = "PRIORITY", nullable = false) int priority;

虽然有注解检查该字段不能为null,但是如果不给该字段传值,该字段也不为null,因为它是基本类型int,默认值是0,就以0作为值赋给了字段priority,与期望不符合;

所以应该@Column(name = "PRIORITY", nullable = false) Integer priority;

这样如果该字段为null,插入到数据库时就会报该字段不能为null的错误!

自定义异常

领域模型命名规约

建议使用 try-with-resources 语句

https://github.com/RhymeXY/java-basic-demos/blob/master/common/src/main/java/com/xy/java/basic/demos/utils/InputFromSystemInUtil.java
Java 7 中引入了 try-with-resources 语句,该语句能保证将相关资源关闭,优于原来的 try-catch-finally 语句,并且使程序代码更安全更简洁。
反例

private void handle(String fileName) {
BufferedReader reader = null;
try {
String line;
reader = new BufferedReader(new FileReader(fileName));
while ((line = reader.readLine()) != null) {
...
}
} catch (Exception e) {
...
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
...
}
}
}
}

正例:

private void handle(String fileName) {
try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
String line;
while ((line = reader.readLine()) != null) {
...
}
} catch (Exception e) {
...
}
}

spring boot 多模块开发时,依赖注入其他模块的bean失败

比如A模块依赖B模块,A需要自动注入B模块的一个Bean,启动时找不到B模块的Bean依赖,极大的可能是A模块启动类所在的包和B模块所在的包名不一样,所以扫描不到B模块,在A模块的启动类加上@ComponentScan注解扫描B模块的包,如果需要B模块的Bean需要配置文件,A模块还需要配置。

被final修饰的变量

被final修饰的变量只能初始化一次,所以它的引用不能改变,引用的对象实例可以改变!

public class FinalObjectTest {

    @Test
public void test(){
A a = new A(1);
A temp = new A(9);
final A finalA = a;
a.setValue(2);
System.out.println(finalA.value); //
System.out.println(a.value); // 2
// finalA = temp; 会报错
// 被final修饰的变量只能初始化一次,所以它的引用不能改变,引用的对象实例可以改变! } @Data
@AllArgsConstructor
private class A {
private int value;
}
}

Java interface

Java的接口interface,无父类,不是Object类的子类。

在Java里用正则表达式,注意性能

private static final Pattern pattern = Pattern.compile("^[A-Za-z\\u4e00-\\u9fa5][A-Za-z\\u4e00-\\u9fa50-9_\\-]{0,31}$");

Pattern.compile底层代码方法会编译一次正则表达式

Matcher matcher = pattern.matcher(内容)

pattern对象的matcher方法,如果没有编译,会编译一次,上面Pattern.compile方法如果编译了这里不会编译;

注意!!!一定要保证一个正则表达式只编译(初始化)一次。

再比如String类中的replace、replaceAll方法底层也是用的Pattern.compile,每调用一次replace*方法都会编译一次,效率太低了,所以像上面一样定义一个private static final Pattern pattern = Pattern.compile(regex),保证一个正则表达式值初始化一次,再利用matcher匹配字符串调用replace(String replacement)方法。

利用策略模式和工厂模式优化多个if-else

多个if-else通常逻辑看起来很复杂,不方便维护,用策略模式和工厂模式优化

https://www.cnblogs.com/theRhyme/p/10339382.html

Collection (如List、Set) 的 "All elements are null"的情况

一个Java集合的Size是1,虽然它!=null && size>0,但是它内容是"All elements are null",相当于它就是空的!

这时候通过集合类的removeAll方法移除这些值为"All elements are null"的属性:

tourists.removeAll(Collections.singleton(null));

https://stackoverflow.com/questions/4819635/how-to-remove-all-null-elements-from-a-arraylist-or-string-array

调用Set.addAll()方法时抛UnsupportedOperationException异常

上面的Set是Map中keySet的返回结果。

程序中这样两句代码运行时,抛UnsupportedOperationException异常。
最初感觉很奇怪,Map.keySet()方法返回一个Set呀,Set明明是支持add()、addAll()方法的,怎么会抛“不支持操作”异常呢。
结果发现,问题不是出在Set上,而是出在Map的keySet()方法上。

下面是摘自API帮助文档的说明

Map中的方法public Set keySet()返回此映射中所包含的键的 set 视图。该集合受映射的支持,所以映射的变化也反映在该集合中,反之亦然。该集合支持元素的移除,通过 Iterator.remove、Set.remove、removeAll、retainAll 和 clear 操作,从该映射中移除相应的映射关系。它不支持 add 或 addAll 操作。

相当于在Map.keySet()得到的集合中插入元素,故此时Set不再支持addAll()方法。

所以应该new一个Set,再使用addAll:

Array转ArrayList

当需要把Array转成ArrayList的时候,开发人员经常这样做:

List<String> list = Arrays.asList(arr);

Arrays.asList()会返回一个ArrayList,但是要特别注意,这个ArrayList是Arrays类的静态内部类,并不是java.util.ArrayList类。java.util.Arrays.ArrayList类实现了set(), get(),contains()方法,但是并没有实现增加元素的方法(事实上是可以调用add方法,但是没有具体实现,仅仅抛出UnsupportedOperationException异常),因此它的大小也是固定不变的。为了创建一个真正的java.util.ArrayList,你应该这样做:

ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(arr));

ArrayList的构造方法可以接收一个Collection类型,而java.util.Arrays.ArrayList已经实现了该接口。

判断一个数组是否包含某个值

开发人员经常这样做:

Set<String> set = new HashSet<String>(Arrays.asList(arr));
return set.contains(targetValue);

以上代码可以正常工作,但是没有必要将其转换成set集合,将一个List转成Set需要额外的时间,其实我们可以简单的使用如下方法即可:

Arrays.asList(arr).contains(targetValue);

或者

for(String s: arr){
if(s.equals(targetValue))
return true;
}
return false;

第一种方法可读性更强。

RabbitMQ消费者抛异常未捕获控制台日志持续打印问题

消费者接受消息,进行一系列处理,但是由于某些原因处理过程中该消费者的抛出了异常,并且不捕获(直接 throws IOException 抛出去);

由于抛出了IOException,那么这条消息就会再次被发送到该队列,消费者就再次收到,而消费者抛出异常,所以就形成了一个死循环(除非不再有类似IO的异常),那么控制台日志就一直打印该消费者的抛出异常。

解决方法:https://www.cnblogs.com/theRhyme/p/10758249.html

TimeUnit枚举

TimeUnit是java.util.concurrent包下面的一个枚举类,TimeUnit提供了可读性更好的线程暂停操作。

在JDK5之前,一般我们暂停线程是这样写的:

Thread.sleep(2400000)//可读性差

可读性相当的差,一眼看去,不知道睡了多久;

在JDK5之后,我们可以这样写:

 TimeUnit.SECONDS.sleep(4);
 TimeUnit.MINUTES.sleep(4);
 TimeUnit.HOURS.sleep(1);
 TimeUnit.DAYS.sleep(1);

清晰明了;

另外,TimeUnit还提供了便捷方法用于把时间转换成不同单位,例如,如果你想把秒转换成毫秒,你可以使用下面代码

TimeUnit.SECONDS.toMillis(44);// 44,000

Java访问控制

Java中的private、默认、protected、public访问控制。

这个老是忘记。

Java代码优化

https://www.cnblogs.com/xrq730/p/4865416.html

参考来源:

https://blog.csdn.net/woyaoxuejavaya/article/details/52472508

https://www.cnblogs.com/chenpi/p/5508949.html#_label1

https://www.cnblogs.com/chenpi/p/5614290.html#_label9

https://www.cnblogs.com/theRhyme/p/10758249.html

https://zhidao.baidu.com/question/1510955557965485900.html

https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247485599&idx=1&sn=d83ff4e6b1ee951a0a33508a10980ea3&chksm=cea24754f9d5ce426d18b435a8c373ddc580c06c7d6a45cc51377361729c31c7301f1bbc3b78&token=1328169465&lang=zh_CN&scene=21#wechat_redirect

https://github.com/alibaba/p3c/blob/master/阿里巴巴Java开发手册(华山版).pdf

Java开发经常容易犯的错误的更多相关文章

  1. 十个JAVA程序员容易犯的错误

    十个JAVA程序员容易犯的错误 1. Array 转 ArrayList 一般开发者喜欢用: List<String> list = Arrays.asList(arr); Arrays. ...

  2. Java开发最常犯的10个错误,打死都不要犯!

    原文:http://www.programcreek.com/2014/05/top-10-mistakes-java-developers-make/ 译文:cnblogs.com/chenpi/p ...

  3. 【微信Java开发 --番外篇】错误解析

    虽然在微信开发过程中,会有微信公众平台开发者文档中的<全局返回码>作为错误的参考对比:但是依旧的,会觉得有时候的问题莫名其妙.[注:本人使用weixin-java-tools进行开发] 下 ...

  4. python开发中容易犯的错误整合

    写在前面 长期更新的博文.多数是一些比较隐蔽的问题.欢迎留言补充. pip并不是那么安逸 pip安装对于开发者来说确实是一种解放.可以自动安装依赖包,但执行最简单的pip安装命令时,并不是所有的依赖都 ...

  5. java中自己常犯的错误汇总

    package debug; /** 1.定义一个公共的动物类,包含名字.年龄.颜色和吃饭东西方法 2.定义一个猫类,继承动物类,同时拥有玩游戏的本领 3.定义一个狗类,继承动物类,同时拥有看门的本领 ...

  6. Java开发人员最常犯的10个错误

    这个列表总结了10个Java开发人员最常犯的错误. Array转ArrayList 当需要把Array转成ArrayList的时候,开发人员经常这样做: List<String> list ...

  7. 总结下java经常犯的错误

    编写代码是一种艺术,认识错误是我们代码改进的重要途径之一.以下情况并非大家都能碰到过,但希望提高代码质量的人都引以为戒.以下各种情况,都是初学者经常犯的错误. 1.1       字符串没有判断是否为 ...

  8. Java程序员常犯的10个错误

      本文总结了Java程序员常犯的10个错误. #1. 把Array转化成ArrayList 把Array转化成ArrayList,程序员经常用以下方法: List<String> lis ...

  9. Java 程序员容易犯的10个SQL错误

    Java程序员编程时需要混合面向对象思维和一般命令式编程的方法,能否完美的将两者结合起来完全得依靠编程人员的水准: 技能(任何人都能容易学会命令式编程) 模式(有些人用“模式-模式”,举个例子,模式可 ...

随机推荐

  1. FPGA Asynchronous FIFO设计思路(2)

    FPGA Asynchronous FIFO设计思路(2) 首先讨论格雷码的编码方式: 先看4bit的格雷码,当MSB为0时,正向计数,当MSB为1时,即指针已经走过一遍了,最高位翻转,此时的格雷码是 ...

  2. net use远程重启服务器

      在命令行工具中分别输入如下3条命令 net use \\10.10.1.100\ipc$ Password /user:Username shutdown -f -r -m \\10.10.1.1 ...

  3. RN 获取组件的宽度和高度

    https://www.cnblogs.com/zhiyingzhou/p/7471212.html https://blog.csdn.net/calvin_zhou/article/details ...

  4. [UE4]VR手柄按键参考

    一.VR手柄按键 二.Gamepad菜单往下拉 三.Shouder Button,在一般游戏当中是用作菜单键,按一下Shouder Button会出现游戏菜单. 四.Face Buttons:可以触摸 ...

  5. mybatis与数据库访问相关的配置以及设计

    mybatis与数据库访问相关的配置以及设计 mybatis不管如何NB,总是要与数据库进行打交道.通过提问的方式,逐步深入 我们常用的MyBatis配置中哪些是与数据库相关? 数据源配置: < ...

  6. spring boot profiles 实现多环境下配置切换 docker版

    1,前言 开发环境总需要调试,docker直接部署不需要调试,环境配置不一样,这里的目的只是,在docker文件环境与开发环境使用不同的配置文件,项目结构如下 2,设置项目配置文件 默认配置文件 ap ...

  7. Troubleshooting 10g and 11.1 Clusterware Reboots (文档 ID 265769.1)

    Troubleshooting 10g and 11.1 Clusterware Reboots (文档 ID 265769.1) This document is intended for DBA' ...

  8. Linq to SQL -- 入门篇

    一.什么是Linq Linq是语言集成查询(Language Integrated Query)的简称,是visual Studio 2008和.NET Framework 3.5版本中一项突破性的创 ...

  9. Splunk 丰富数据方法

    方法1: 查找 Step 1.创建CSV文件,首字段为索引字段(关联字段) 2.导入CSV文件,Settings, Lookups, Lookup tables files 3.配置Lookup de ...

  10. 软件工程个人作业四--alpha阶段个人总结

    个人总结 (1)个人总结 类型 具体技能和面试问题 现在的回答 毕业找工作的时间 语言 最拿手的计算机语言之一,代码量多少 C语言相对熟悉一点 软件实现 你有没有在别的代码的基础上改进,你是怎么读懂别 ...