专业素养瞎扯淡

成为一个专业的程序员的素养

高素质注释

错误示范

1、在不需要注释的地方使用注释

// 获得所有最长的字符串
function longestString(inputArray) {
    
    
	// 初始化将第0个字符串的长度设置为最大长度
	let length = inputArray[0].length;
	
	for (let i = 1; i < inputArray.length; i++) {
    
    
		
		// 检查当前字符串长度是否大于最大长度
		if (length < inputArray[i].length) {
    
    
			length = inputArray[i].length;
		}
	}
	
	// 过滤小于最大长度的字符串
	const strs = inputArray.filter(() => {
    
    
		return word.length === length;
	});
	
	return strs;
}

去除不必要的注释,使用更清晰的变量、方法的命名

function getLongestStrings(inputArray) {
    
    
	let longestWordLength = inputArray[0].length;
	
	for (let i = 1; i < inputArray.length; i++) {
    
    
	
		if (longestWordLength < inputArray[i].length) {
    
    
			longestWordLength = inputArray[i].length;
		}
	}
	
	const longestWords = inputArray.filter(() => word.length === length);
	
	return longestWords;
}

2、一般来说不优雅的代码才需要注释
3、不明确的注释,甚至误导别人的注释
4、注释而不删除遗留的代码
5、版本控制代码

正确示范

高素质变量


高素质函数


其他素质


高素质结构(SOLID 原则)

单一职责原则(SRP)
开放封闭原则(OCP)
里氏替换原则(LSP)
接口隔离原则(ISP)
依赖倒置原则(DIP)

高素质异常

概述

Java中的异常处理通过向用户显示有意义的消息并继续(或终止)程序流,提供了一种处理抛出异常情况的方法
try catch finally
……
此处省略300字

Exception Hierarchy in Java

Exception

所有非 RunTimeException 的 Exception 被称为 Checked Exception

  • IOException
  • FileNotFoundException
  • ParseException
  • ClassNotFoundException
  • CloneNotSupportedException
  • InstantiationException
  • InterruptedExcpetion
  • NoSuchMethodException
  • NoSuchFieldException

在异常层次结构中。如果异常是 RuntimeException 的子类,则它是 unchecked exception 。通过 try catch 块,也可以捕获 unchecked exception ,但不必这样做。因为它在编译时无法验证,因此,被称为 “unchecked”

  • ArrayIndexOutOfBoundsException
  • ClassCastException
  • IllegalArgumentException
  • IllegalStateException
  • NullPointerException
  • NumberFormatException
  • AssertionError
  • ExceptionInInitializerErr
  • StackOverflowError
  • NoClassDefFoundError

CheckedExcpetion 和 UnCheckedException 的区别

  • UncheckedException 是 RuntimeException 的子类
  • UncheckedException 没有包含在 try 代码块中,也能编译通过
  • 设计 CheckedException 的目的是,在有合理的机会恢复的情况下,减少异常情况发生的数量。UncheckedException 主要是编程错误
  • 预期无法恢复的异常,告诉调用方,是没有意义的(比如你告诉调用方服务器 500 错误,是没有意义的。这种时候你只需要记录日志,并修复程序)

Exception 的类型

Checked Exception: 这些是应用程序应该预期并从中恢复的特殊情况
Unchecked/Runtime Exception: 这些是应用程序外部的异常情况,应用程序通常无法预料或恢复它们
Error: 它定义了不希望被程序捕获的异常

Exception 的优势

  • 保持应用程序的正常流程
  • 将错误处理代码与常规代码分离
  • 为故障情况提供适当的消息
  • 防止程序自动终止

Java7 的 AutoCloseable

 try (AutoCloseableObjecct app = new AutoCloseableObjecct()) {
    
    
 	System.out.println("--执行main方法--");
} catch (Exception e) {
    
    
	System.out.println("--exception--");
} finally {
    
    
	System.out.println("--finally--");
}

Finally

// the result is 20
static int getValue() {
    
    
	try{
    
    
		return 10;
	} finally {
    
    
		return 20;
	}
}
  • 在嵌套try块的情况下,可以将finally块与相应的try块相关联
  • 从finally返回值不是一个好主意,因为它可能会导致忽略方法中未捕获的异常。
  • 如果在执行try或catch代码时JVM退出(通过System.exit() 或JVM崩溃),那么finally块可能不会执行。在多线程情况下,如果执行try或catch代码的线程被中断或停止,那么即使整体上应用程序继续运行,finally块也可能不被执行

Exception 传播

当方法发生异常时,将(在发生异常的地方)创建一个异常对象并抛出它。创建的异常对象包含:错误信息、错误类型信息和错误发生时程序状态

Exception 重写

  • 如果超类方法没有使用 throws 子句声明任何异常,那么子类重写的方法不能声明任何 checked 异常,但是它可以使用throws子句声明 unchecked 异常
  • 如果超级类方法已经使用 throws 子句声明了一个 checked 异常,那么子类重写的方法可以做以下三件事之一
    • 子类可以声明与在超级类方法中声明的相同的异常
    • 子类可以声明在超级类方法中声明的异常的子类型异常。但是子类方法不能声明层次结构中高于超类的异常。
    • 子类方法可以选择根本不声明任何异常

自定义异常

根据java文档,如果您对下面的任何问题回答“是”,那么您应该编写自己的自定义异常类;否则,您可以使用现有的异常

  • java平台中没有的异常类型
  • 其他库抛出的异常,与你的代码异常分开,方便调用者区分
  • 你的代码抛出了多个相关的异常

仅当您希望异常具有更高的可读性,且java中的现有异常类中不存在该异常类型,才创建自定义异常类。否则,请坚持已存在的异常之一

为了决定是将您自己的自定义异常编写为checked异常还是unchecked异常,规则如下

  • 如果代码中可以采取一些措施从预期的错误中恢复,则将自定义异常设置为 checked 异常。另一方面,如果用户在出现错误时无法执行任何有用的操作,则将自定义异常设置为 unchecked 异常

  • 大多数情况下,自定义异常的唯一功能是记录错误。在这种情况下,它绝对应该是一个 unchecked 异常。

  • 程序上的 BUG 一般偏向于使用 unchecked 异常。编码上的错误我指的是无效的输入参数或不正确的方法实现,应用程序无法在中期执行中解决问题。它能做的最好的事情是记录问题并等待开发人员在以后修复它

  • 如果没有为客户端代码提供任何有用的信息,请不要创建新的自定义异常类。

  • 如果用户可以采取一些措施从异常中恢复,请将自定义异常作为 checked 异常。如果用户无法做任何有用的事情,则为 unchecked 异常

  • 通常自定义异常仅用于日志记录目的,因此最好使用 unchecked 异常。因为,我们可以在 try-catch 块中捕获 unchecked 异常。只是编译器不会强迫我们这样做

  • 尝试在异常消息中提供导致异常的参数。栗如年龄大于 200 异常,年龄也附加在异常消息中。这使得程序员寻找错误原因变得容易

  • throwable 类提供了四个构造,自定义异常类中尝试提供所有这些构造。至少提供三个:无参构造,一个带有消息字符串的构造,接受另一个 throwable 的构造。最后一个很重要,因为我们正在将最初抛出的错误包装在一些自定义异常中并重新抛出。在这种情况下,将原始异常作为原因参数有助于找到错误的根本原因

怎样正确的使用 Exception

  • 不要不处理异常
    • 对于 checked exception 不要写个 Catch 然后不处理异常
      • 在java中 checked excpetion 的目的是让程序有机会从提出的异常中恢复。因此,catch{}或catch{e.printtrace();}或catch{logger.error(e)} 并继续并不是最佳做法
  • 不要丢弃原始异常 public Exception(string message, Throwable cause)
  • 自定异常区分 checked exception 和 unchecked exception
  • 自定义异常取名是注意参考已经存在的异常的命名风格,注意继承已经存在的异常
  • 异常将会影响应用程序的整体性能。如果您可以使用布尔变量来指示操作是否成功,请不要捕获抛出异常,尝试将布尔变量返回给调用程序 (100 个异常捕获能耗费服务器 0.7 秒的时间)
  • 在开发接口程序时,在 javadoc 中使用 @throws 来明确指定方法抛出的异常
  • 定义和处理异常对性能来说是一项昂贵的操作,仅适用于特定的情况。使用异常来代替流程控制将会影响整体性能。
    • 栗如:数组长度和空值检查,不要依靠异常处理来做到这一点
  • 我们应该始终 logger 异常消息,而抛出的异常则应提供清晰的异常原因消息。如果可能,在异常消息中附加值
  • 应该避免在 catch 块中 logging 然后 throw 异常,应该直接抛出异常
catch (NoSuchFieldException exp) {
    
    
    Log.error("Exception occurred", exp);
    throw exp;
}
  • 保持松散的耦合,比如不要将 Dao 层的 SQLException 抛给 Service 层
catch (SQLException ex) {
    
    
    throw new RuntimeException("DB error", ex);
}

猜你喜欢

转载自blog.csdn.net/u012296499/article/details/104160226
今日推荐