原始代码

定义了一个类,其中没有使用任何的内部类。

有一个方法如下:

  [java]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@Override public String replace(final List<CharsScanMatchItem> charsScanMatchItemList, final String originalString, final CharsScanContext context) { // 基本属性 final char[] oldChars = originalString.toCharArray(); final ICharsReplaceFactory charsReplaceFactory = context.getCharsReplaceFactory(); final StringBuilder stringBuilder = new StringBuilder(); // 排序,理论上是从前往后的。 // 但是因为策略不同,先做一次排序 Olog(N) if(charsScanMatchItemList.size() > 1) { Collections.sort(charsScanMatchItemList, new Comparator<CharsScanMatchItem>() { @Override public int compare(CharsScanMatchItem o1, CharsScanMatchItem o2) { //1. 先使用开始下标 int startIndexDiff = o1.getStartIndex() - o2.getStartIndex(); if(startIndexDiff != 0) { return startIndexDiff; } //2. 如果相同,则看优先级 return o1.getPriority() - o2.getPriority(); } }); } // 其他逻辑 return stringBuilder.toString(); }

jvisual 观察

当时把这个类 CharsCore 定义为单例,然后发现每次还是会不断创建新的对象类:

  [plaintext]
1
xxx.CharsCore$1

很奇怪,这个 $1 是一个什么东西?

idea 查看 target class 文件

idea 直接查看 target class 文件下的信息,发现没有额外的文件信息。

其实是 idea 把 $1 的文件过滤掉了。

文件夹查看 class 文件

直接文件夹打开 target 文件。

就可以看到后缀为 $1 的 class 文件。

查看文件内容

可以把 class 文件直接拖到 idea 中打开:

内容如下:

  [java]
1
2
3
4
5
6
7
8
9
10
class CharsCoreCommon$1 implements Comparator<CharsScanMatchItem> { CharsCoreCommon$1(CharsCoreCommon this$0) { this.this$0 = this$0; } public int compare(CharsScanMatchItem o1, CharsScanMatchItem o2) { int startIndexDiff = o1.getStartIndex() - o2.getStartIndex(); return startIndexDiff != 0 ? startIndexDiff : o1.getPriority() - o2.getPriority(); } }

其实就是我们在 Collections.sort 方法中使用了匿名内部类导致的。

所以把这个类单独提取出来,对性能理论上有一定的提升。

参考资料

https://juejin.cn/s/char%E6%95%B0%E7%BB%84%E8%BD%ACbyte%E6%95%B0%E7%BB%84