-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCreateEntry.java
102 lines (91 loc) · 3.03 KB
/
CreateEntry.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
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
100
101
102
package other;
import org.junit.jupiter.api.Test;
import sun.misc.Unsafe;
import java.io.*;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.Field;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class CreateEntry {
/**
* new 关键字
* 使用构造函数: true
*/
@Test
public void byNew() {
int old = Entry.getUseConstructorCount();
Entry entry = new Entry();
assertEquals(old + 1, Entry.getUseConstructorCount());
}
/**
* 复制
* 使用构造函数: false
* 需实体类实现{@link Cloneable}
*/
@Test
public void byClone() throws Throwable {
Entry src = new Entry();
int old = Entry.getUseConstructorCount();
Entry clone = (Entry) src.clone();
assertEquals(old, Entry.getUseConstructorCount());
}
/**
* 反序列化
* 使用构造函数: false
* 需实体类实现{@link Serializable}
*/
@Test
public void bySerialization() throws Throwable {
Entry src = new Entry();
byte[] bytes;
try (ByteArrayOutputStream os = new ByteArrayOutputStream();
ObjectOutputStream outputStream = new ObjectOutputStream(os)){
outputStream.writeObject(src);
bytes = os.toByteArray();
}
int old = Entry.getUseConstructorCount();
Entry serialization;
try (ByteArrayInputStream is = new ByteArrayInputStream(bytes);
ObjectInputStream inputStream = new ObjectInputStream(is)) {
serialization = (Entry) inputStream.readObject();
}
assertEquals(old, Entry.getUseConstructorCount());
}
/**
* 反射
* 使用构造函数: true
* 高版本下反射API内部采用方法句柄{@link #byMethodHandles()}
*/
@Test
public void byReflect() throws Throwable {
int old = Entry.getUseConstructorCount();
Entry entry = Entry.class.getConstructor().newInstance();
assertEquals(old + 1, Entry.getUseConstructorCount());
}
/**
* 方法句柄
* 使用构造函数: true
*/
@Test
public void byMethodHandles() throws Throwable {
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodHandle constructor = lookup.findConstructor(Entry.class, MethodType.methodType(void.class));
int old = Entry.getUseConstructorCount();
Entry entry = (Entry) constructor.invokeExact();
assertEquals(old + 1, Entry.getUseConstructorCount());
}
/**
* 直接分配内存
* 使用构造函数: false
*/
@Test
public void byUnsafe() throws Throwable {
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
Unsafe unsafe = (Unsafe) field.get(null);
int old = Entry.getUseConstructorCount();
Entry entry = (Entry) unsafe.allocateInstance(Entry.class);
assertEquals(old, Entry.getUseConstructorCount());
}
}