0717-7821348
欢乐彩票进入网址

欢乐彩票进入网址

您现在的位置: 首页 > 欢乐彩票进入网址
怎么消除java项目的废物代码
2019-11-26 22:12:54
因各人的才能不同,才智不同,写出来的代码也是良莠不齐.废物代码铢积寸累,不尽不美观,功率还很低.废物代码的发生是你不会,仍是懒的去修正呢?下面给出一些规范性的主张,期望您能采用

一. 让代码功能更高

需求 Map 的主键和取值时,应该迭代 entrySet()

当循环中只需求 Map 的主键时,迭代 keySet() 是正确的。可是,当需求主键和取值时,迭代 entrySet() 才是更高效的做法,比先迭代 keySet() 后再去 get 取值功能更佳。

反例:

Map map = ...;
for (String key : map.keySet()) {
String value = map.get(key);
...
}

正例:

Map map = ...;
for (Map.Entry entry : map.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
...
}

应该运用Collection.isEmpty()检测空

运用 Collection.size() 来检测空逻辑上没有问题,可是运用 Collection.isEmpty()使得代西餐码更易读,而且能够获得更好的功能。任何 Collection.isEmpty() 完成的时刻复杂度都是 O(1) ,可是某些 Collection.size() 完成的时刻复杂度或许是 O(n) 。

反例:

if (collection.size() == 0) {
...
}

正例:

if (collection.isEmpty()) {
...
}

假如需求还需求检测 null ,可采用CollectionUtils.isEmpty(collection)和CollectionUtils.isNotEmpty(collection)。

不要把调集目标传给自己


此外,由于某些办法要求参数在履行期间坚持不变,因而将调集传递给本身或许会导致反常行为。

反例:

List list = new ArrayList<>();
list.add("Hello");
list.add("World");
if (list.containsAll(list)) { // 无意义,总是回来true
...
}
list.removeAll(list); // 功能差, 直接运用clear()

调集初始化尽量指定巨细

java的调集类用起来非常便利,可是看源码可知,调集也是有巨细约束的。每次扩容的时刻复杂度很有或许是 O(n) ,所以尽量指定可预知的调集巨细,能削减调集的扩容次数。

反例:

int[] arr = new int[]{1, 2, 3};
List list = new ArrayList<>();
for (int i : arr) {
list.add(i);
}

正例:

int[] arr = new int[]{1, 2, 3};
List list = new ArrayList<>(arr.length);
for (int i : arr) {
list.add(i);
}

字符串拼接运用 StringBuilder

一般的字符串拼接在编译期 java 会进行优化,可是在循环中字符串拼接, java 编译期无法做到优化,所以需求运用 StringBuilder 进行替换。

反例:

String s = "";
for (int i = 0; i < 10; i++) {
s += i;
}

正例:

String a = "a";
String b = "b";
String c = "c";
String s = a + b + c; // 没问题,java编译器会进行优化
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10; i++) {
sb.append(i); // 循环中,java编译器无法进行优化,所以要手动运用StringBuilder
}

List 的随机拜访

我们都知道数组和链表的差异:数组的随机拜访功率更高。当调用办法获取到 List 后,假如想随机拜访其间的数据,并不知道该数组内部完成是链表仍是数组,怎么办呢?能够判别它是否完成* RandomAccess *接口。

正例:

// 调用他人的服务获取到list
List list = otherService.getList();
if (list instanceof RandomAccess) {
// 内部数组完成,能够随机拜访
System.out.println(list.get(list.size() - 1));
} else {
// 内部或许是链表完成,随机拜访功率低
}

频频调用 Collection.contains 办法请运用 Set

在 java 调集类库中,List 的 contains 办法遍及时刻复杂度是 O(n) ,假如在代码中需求频频调用 contains 办法查找数据,能够先将 list 转换成 HashSet 完成,将 O(n) 的时刻复杂度降为 O(1) 。

反例:

ArrayList list = otherService.getList();
for (int i = 0; i <= Integer.MAX_VALUE; i++) {
// 时刻复杂度O(n)
list.contains(i);
}

正例:

ArrayList list = otherService.getList();
Set set = new HashSet(list);
for (int i = 0; i <= Integer.MAX_VALUE; i++) {
// 时刻复杂度O(1)
set.contains(i);
}

二. 让代码更高雅


长整型常量后增加大写 L

在运用长整型常量值时,后边需求增加 L ,有必要是大写的 L ,不能是小写的 l ,小写 l 简单跟数字 1 混杂而形成误解。

反例:

long value = 1l;
long max = Math.max(1L, 5);

正例:

long value = 1L;
long max = Math.max(1L, 5L);


不要运用魔法值

当你编写一段代码时,运用魔法值或许看起来很清晰,但在调试时它们却不显得那么清晰了。这便是为什么需求把魔法值界说为可读取常量的原因。可是,-1、0 和 1不被视为魔法值。


反例:

for (int i = 0; i < 100; i++){
...
}
if (a == 100) {
...
}

正例:

private static final int MAX_COUNT = 100;
for (int i = 0; i < MAX_COUNT; i++){
...
}
if (count == MAX_COUNT) {
...
}


不要运用调集完成来赋值静态成员变量

关于调集类型的静态成员变量,不要运用调集完成来赋值,应该运用静态代码块赋值。

反例:

private static Map map = new HashMap() {
{
put("a", 1);
put("b", 2);
}
};
private static List list = new ArrayList() {
{
add("a");
add("b");
}
};

正例:

private static Map map = new HashMap<>();
static {
map.put("a", 1);
map.put("b", 2);
};
private static List list = new ArrayList<>();
static {
list.add("a");
list.add("b");
};

主张运用 try-with-resources 句子

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) {
...
}
}


删去未运用的私有办法和字段

删去未运用的私有办法和字段,使代码更简练更易保护。若有需求再运用,能够从前史提交中找回。

反例:

public class DoubleDemo1 {
private int unusedField = 100;
private void unusedMethod() {
...
}
public int sum(int a, int b) {
return a + b;
}
}

正例:

public class DoubleDemo1 {
public int sum(int a, int b) {
return a + b;
}
}

删去未运用的局部变量

删去未运用的局部变量,使代码更简练更易保护。

反例:

public int sum(int a, int b) {
int c = 100;
return a + b;
}

正例:

public int sum(int a, int b) {
return a + b;
}

删去未运用的办法参数

未运用的办法参数具有误导性,删去未运用的办法参数,使代码更简练更易保护。可是,由于重写办法是根据父类或接口的办法界说,即使有未运用的办法参数,也是不能删去的。

反例:

public int sum(int a, int b, int c) {
return a + b;
}

正例:

public int sum(int a, int b) {
return a + b;
}

删去表达式的剩余括号

对应表达式中的剩余括号,有人以为有助于代码阅览,也有人以为彻底没有必要。关于一个了解 Java 语法的人来说,表达式中的剩余括号反而会让代码显得更繁琐。

反例:

return (x);
return (x + 2);
int x = (y * 3) + 1;
int m =怎么消除java项目的废物代码 (n * 4 + 2);

正例:

return x;
return x + 2;
int x = y * 3 + 1;
int m = n * 4 + 2;

东西类应该屏蔽结构函数

东西类是一堆静态字段和函数的调集,不该该被实例化。可是,Java 为每个没有清晰界说结构函数的类增加了一个隐式公有结构函数。所以,为了防止 java "小白"运用有误,应该显式界说私有结构函数来屏蔽这个隐式公有结构函数。

反例:

public class MathUtils {
public static final double PI = 3.1415926D;
public static int sum(int a, int b) {
return a + b;
}
}

正例:

public class MathUtils {
public static final double PI = 3.1415926D;
private MathUtils() {}
public static int sum(int a, int b) {
return a + b;
}
}

删去剩余的反常捕获并抛出

用 catch 句子捕获反常后,什么也不进行处理,就让反常从头抛出,这跟不捕获反常的作用相同,能够删去这块代码或增加其他处理。

反例:

private static String readFile(String fileName) throws IOException {
try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
String line;
StringBuilder builder = new StringBuilder();
while ((line = reader.readLine()) != null) {
builder.append(line);
}
return builder.toString();
} catch (Exception e) {
throw e;
}
}

正例:

private static String readFile(String fileName) throws IOException {
try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
String line;
StringBuilder builder = new StringBuilder();
while ((line = reader.readLine()) != null) {
builder.append(line);
}
return builder.toString();
}
}

公有静态常量应该经过类拜访

尽管经过类的实例拜访公有静态常量是答应的,可是简单让人它误以为每个类的实例都有一个公有静态常量。所以,公有静态常量应该直接经过类拜访。

反例:

public class User {怎么消除java项目的废物代码
public static final String CONST_NAME = "name";
...
}
User user = new User();
String nameKey = user.CONST_NAME;

正例:

public class User {
public static final String CONST_NAME = "name";
...
}
String nameKey = User.CONST_NAME;

不要用NullPointerException判别空

空指针反常应该用代码躲避(比方检测不为空),而不是用捕获反常的办法处理。

反例:

public String getUserName(User user) {
try {
return user.getName();
} catch (NullPointerException e) {
return null;
}
}

正例:

public String getUserName(User user) {
if (Objects.isNull(user)) {
return null;
}
return user.getName();
}

运用String.valueOf(value)代替""+value

当要把其它目标或类型转化为字符串时,运用 String.valueOf(value) 比""+value 的功率更高。

反例:

int i = 1;
String s = "" + i;

正例:

int i = 1;
String s = String.valueOf(i);


过期代码增加 @Deprecated 注解

当一段代码过期,但为了兼容又无法直接删去,不期望今后有人再运用它时,能够增加 @Deprecated 注解进行符号。在文档注释中增加 @deprecated 来进行解说,并供给可代替计划。

正例:

/**
* 保存
*
* @deprecated 此办法功率较低,请运用{@link newSave()}办法替换它
*/
@Deprecated
public void save(){
// do something
}

三. 让代码远离 bug

制止运用结构办法 BigDecimal(double)

BigDecimal(double) 存在精度丢失危险,在准确核算或值比较的场景中或许会导致事务逻辑反常。

反例:

BigDecimal value = new BigDecimal(0.1D); // 0.100000000000000005551115...

正例:

BigDecimal value = BigDecimal.valueOf(0.1D);; // 0.1

回来空数组和空调集而不是 null

回来 null ,需求调用方强制检测 null ,不然就会抛出空指针反常。回来空数组或空调集,有效地防止了调用方由于未检测 null 而抛出空指针反常,还能够删去调用方检测 null 的句子使代码更简练。

反例:

public static Result[] getResults() {
return null;
}
public static List getResultList() {
return null;
}
public static Map getResultMap() {
return null;
}
public static void main(String[] args) {
Result[] results = getResults();
if (results != null) {
for (Result result : results) {
...
}
}
List resultList = getResultList();
if (resultList != null) {
for (Result result : resultList) {
...
}
}
Map resultMap = getResultMap();
if (resultMap != null) {
for (Map.Entry resultEntry : resultMap) {
...
}
}
}

正例:

public static Result[] getResults() {
return new Result[0];
}
public static List getResultList() {
return Collections.emptyList();
}
public static Map getResultMap() {
return Collections.emptyMap();
}
public static void main(String[] args) {
Result[] results = getResults();
for (Result result : results) {
...
}
List resultList = getResultList();
for (Result result : resultList) {
...
}
Map resultMap = getResultMap();
for (Map.Entry resultEntry : resultMap) {
...
}
}

优先运用常量或确认值来调用 equals 办法

目标的 equals 办法简单抛空指针反常,应运用常量或确认有值的目标来调用 equals 办法。当然,运用 java.util.Objects.equals() 办法是最佳实践。

反例:

public void isFinished(OrderStatus status) {
return status.equals(OrderStatus.FINISHED); // 或许抛空指针反常
}

正例:

public void isFinished(OrderStatus status) {
return OrderStatus.FINISHED.equals(status);
}
public v怎么消除java项目的废物代码oid isFinished(OrderStatus status) {
return Objects.equals(status, OrderStatus.FINISHED);
}

枚举的特点字段有必要是私有不可变

枚举通常被作为常量运用,假如枚举中存在公共特点字段或设置字段办法,那么这些枚举常量的特点很简单被修正。抱负情况下,枚举中的特点字段是私有的,并在私有结构函数中赋值,没有对应的 Setter 办法,最好加上 final 修饰符。

反例怎么消除java项目的废物代码:

public enum UserStatus {
DISABLED(0, "禁用"),
ENABLED(1, "启用");
public int value;
private String description;
private UserStatus(int value, String description) {
this.value = value;
this.description = description;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}

正例:

public enum UserStatus {
DISABLED(0, "禁用"),
ENABLED(1, "启用");
private final int value;
private final String description;
private UserStatus(int value, String description) {
this.value = value;
this.description = description;
}
public int getValue() {
return value;
}
public String getDescription() {
return description;
}
}


当心String.split(String regex)

字符串 String 的 split 办法,传入的分隔字符串是正则表达式!部分关键字(比方.[]()\| 等)需求转义。

反例:

"a.ab.abc".split("."); // 成果为[]
"a|ab|abc".split("|"); // 成果为["a", "|", "a", "b", "|", "a", "b", "c"]

正例:

"a.ab.abc".split("\\."); // 成果为["a", "ab", "abc"]
"a|ab|abc".split("\\|"); // 成果为["a", "ab", "abc"]

总结

这篇文章,能够说是从事 Java 开发的经验总结,共享出来以供我们参阅。期望能帮我们防止踩坑,让代码愈加高效高雅。

参阅衔接:https://mp.weixin.qq.com/s?__biz=MzIzOTU0NTQ0MA==&mid=2247491534&idx=1&sn=9fb71f0e769441d5916a22576f268855&chksm=e92922c1de5eabd708824acfda3c80bf92a1487a6026d715a6701214f37ac375bfe92e15fb29&mpshare=1&scene=1&srcid=&sharer_sharetime=1570752649802&sharer_shareid=31bed9867e8b711784ce9869e6aa9eba&key=5929baa0c2a91140353253248bea7a382b3e34966fb60e133a2b64438717f63e94e3fe29cafab13d78ce0cdcf296713a89bf1e373b736109ee02a3543007536ec843b68cd9303a43dd548ba87fdedb9c&ascene=1&uin=MTc1NzAzOTc1&devicetype=Windows+10&version=62070141&lang=zh_CN&pass_ticket=TONfPwoUrIwAlLaP0iwzF9mc7kSjvaexnTJl9C%2BJwTA%3D