avatar

正进一步

只有喜欢,才会全情投入,才会成功!!!

不关注架构设计细节的程序员不是一个好架构师

  • Home
  • Tags
  • Categories
  • Archives
  • 2018寄语
effective_51_当心字符串连接的性能

不要使用字符串连接操作符来合并多个字符串,除非性能无关紧要。相反,应该使用StringBuilder的append方法。另一种方法是,使用字符数组,或者每次只处理一个字符串,而不是将它们组合起来。
以为字符串的不可变,当两个字符串连接在一起时,他们的内容就会被拷贝

1
2
3
4
5
StringBuilder b = new StringBuilder(numItems() * LINE_WIDTH);
for(int i = 0; i < numItem(); i++){
b.append(lineForItem(i));
}
return b.toString();
effective_52通过接口引用对象

尽量使用接口引用对象

不用接口引用的情况:

没有合适的接口的情况。例如: 值类型,String和StringBuilder,Random。通常是final类型.
如果程序依赖于实现了某个接口的类的额外方法,例如LinkedHashMap

一个故事讲明白 ThreadLocal
引自于:https://mp.weixin.qq.com/s/aM03vvSpDpvwOdaJ8u3Zgw

可是我不明白的是为什么那个数据结构是个map 呢? : 允许将多个线程变量放到map中.

1
2
3
4
5
6
7
8
9
10
ThreadLocal<String> threadLocalA= new ThreadLocal<String>();

线程1: threadLocalA.set("1234");
线程2: threadLocalA.set("5678");

//------------
ThreadLocal<Integer> threadLocalB = new ThreadLocal<Integer>();

线程1: threadLocalB.set(30);
线程2: threadLocalB.set(40);
effective_49基本类型优先于装箱基本类型

知识:

当程序进行涉及到装箱和拆箱基本类型和混合类型计算时,会进行拆箱

基本类型和装箱基本类型之间的三个主要区别:

1.基本类型只有值,而装箱基本类型具有与它们的值不同的同一性(两个装箱基本类型可以具有相同的值和不同的同一性)

2.基本类型只有功能完备的值,而每个装箱基本类型除了它对应的基本类型的所有功能值之外,还有个非功能值:null

3.基本类型通常比装箱基本类型更节省空间和时间。

适合使用装箱基本类型的地方:

1.作为集合中的元素,键和值。

2.在参数化类型中,必须使用装箱基本类型作为类型参数。

3.在进行反射方法调用时,必须使用装箱基本类型。

effective_46_foreach循环优先于传统的for循环

foreach可以遍历iterable接口
foreach循环在简洁性与预防bug方面有着传统的for循环无法比拟的优势.

除了一下情况:

过滤- 将删除特定元素remove方法
转换- 使用列表迭代器或者数组索引,以便设定元素的值
平行迭代- 如果并行遍历多个集合,就需要显示的控制迭代器和索引变量

effective_45_将局部变量的作用域最小化

http://blog.csdn.net/zhtzyh2012/article/details/46675065

循环提供特殊机会将变量作用域最小化.(无论传统for,还foreach).for循环,都允许声明循环变量,它们的作用域被限定在正好的作用范围之内.(范围包括循环体,以及循环体之前的初始化,测试,更新).如果循环终止之后不再需要循环变量内容,for循环优于while循环.
几乎每个局部变量的声明都应该包含一个初始化表达式.如果没有足够信息来对一个变量进行有意义的初始化,就应该推迟这个声明,直到可以初始化为止.例外情况是与try..catch有关.
for循环比while循环另外优势:更简短,增加可读性.

1
2
3
4
5
6
7
8
9
10
public static void main(String[] args) {
Class<?>cl = null;
try{
cl= Class.forName(args[0]);
}catch (ClassNotFoundException e){
System.err.println("Classnot find");
System.exit(1);
}

}
Jdk_Proxy代理生成过过程源码分析
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
private static final class ProxyClassFactory
implements BiFunction<ClassLoader, Class<?>[], Class<?>>
{
// prefix for all proxy class names
private static final String proxyClassNamePrefix = "$Proxy";

// next number to use for generation of unique proxy class names
private static final AtomicLong nextUniqueNumber = new AtomicLong();

@Override
public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {

Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
for (Class<?> intf : interfaces) {
/*
* Verify that the class loader resolves the name of this
* interface to the same Class object.
*/
Class<?> interfaceClass = null;
try {
interfaceClass = Class.forName(intf.getName(), false, loader);
} catch (ClassNotFoundException e) {
}
if (interfaceClass != intf) {
throw new IllegalArgumentException(
intf + " is not visible from class loader");
}
/*
* Verify that the Class object actually represents an
* interface.
*/
if (!interfaceClass.isInterface()) {
throw new IllegalArgumentException(
interfaceClass.getName() + " is not an interface");
}
/*
* Verify that this interface is not a duplicate.
*/
if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) {
throw new IllegalArgumentException(
"repeated interface: " + interfaceClass.getName());
}
}

String proxyPkg = null; // package to define proxy class in
int accessFlags = Modifier.PUBLIC | Modifier.FINAL;

/*
* Record the package of a non-public proxy interface so that the
* proxy class will be defined in the same package. Verify that
* all non-public proxy interfaces are in the same package.
*/
for (Class<?> intf : interfaces) {
int flags = intf.getModifiers();
if (!Modifier.isPublic(flags)) {
accessFlags = Modifier.FINAL;
String name = intf.getName();
int n = name.lastIndexOf('.');
String pkg = ((n == -1) ? "" : name.substring(0, n + 1));
if (proxyPkg == null) {
proxyPkg = pkg;
} else if (!pkg.equals(proxyPkg)) {
throw new IllegalArgumentException(
"non-public interfaces from different packages");
}
}
}

if (proxyPkg == null) {
// if no non-public proxy interfaces, use com.sun.proxy package
proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
}

/*
* Choose a name for the proxy class to generate.
*/
long num = nextUniqueNumber.getAndIncrement();
String proxyName = proxyPkg + proxyClassNamePrefix + num;

/*
* Generate the specified proxy class.
*/
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
proxyName, interfaces, accessFlags);
try {
return defineClass0(loader, proxyName,
proxyClassFile, 0, proxyClassFile.length);
} catch (ClassFormatError e) {
/*
* A ClassFormatError here means that (barring bugs in the
* proxy class generation code) there was some other
* invalid aspect of the arguments supplied to the proxy
* class creation (such as virtual machine limitations
* exceeded).
*/
throw new IllegalArgumentException(e.toString());
}
}
}
1237