为什么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. OpenStack搭建Q版在控制节点上的环境准备(step2)

    接下来是只需要在控制节点上准备的环境配置.其中虽然NTP服务需要在所有节点上都安装,但NTP服务在控制节点和其他的节点上的配置是不同的,所以不把它放在step1的公共配置中进行准备.如下: 1.配置N ...

  2. Hadoop 2.x 版本的单机模式安装

    Hadoop 2.x 版本比起之前的版本在Hadoop和MapReduce上做了许多变化,主要的变化之一,是JobTracker被ResourceManager和ApplicationManager所 ...

  3. Python学习:函数式编程(lambda, map() ,reduce() ,filter())

    1. lambda: Python 支持用lambda对简单的功能定义“行内函数” 2.map() : 3.reduce() : 4.filter() : map() ,reduce() , filt ...

  4. Robot Framework脚本在jenkins执行完之后无法查看日志

    首先确保Robot Framework Plugin已经安装好,构建结束后test result和log.html等日志文件已显示,只是无法打开查看: 修改tomcat配置:vi tomcat/con ...

  5. VSCode扩展包离线安装

    下载离线包 下载地址:https://marketplace.visualstudio.com/vscode 安装离线包

  6. 重置SQLSERVER表的自增列,让自增列重新计数

    SQL的自增列挺好用,只是开发过程中一旦删除数据,标识列就不连续了 写起来 也很郁闷,所以查阅了一下标识列重置的方法 发现可以分为三种: --- 删除原表数据,并重置自增列truncate table ...

  7. 使用VISIO远程服务器上的ORACLE数据库,反向生成数据库实体关系图

    反向即根据已有的数据库,生成ER图,很多工具都可以实现这一过程,如visio,powerdesigner等,下面文章记录一下我使用VISIO生成远程服务器上的一个数据库ER图过程,供以后自己参考. 1 ...

  8. 移植mysql到ARM(AM335x)

    一,编译ncurses 编译mysql需要依赖ncurses,先编译ncurses 1.下载ncurses 下载路径是ftp://ftp.gnu.org/gnu/ncurses,选择下载的是ncurs ...

  9. SpringCloud注解和配置以及pom依赖说明

    在本文中说明了pom依赖可以支持什么功能,以及支持什么注解,引入该依赖可以在application.properties中添加什么配置. 1.SpringCloud 的pom依赖 序号 pom依赖 说 ...

  10. Kong(v1.0.2)认证

    介绍 上游服务(api或微服务)的流量通常由各种Kong的authentication plugins的应用程序和配置控制.由于Kong的服务实体表示您自己的上游服务的一对一映射,所以最简单的场景是在 ...