{
325 | private int element; // 数据元素
326 | private Node left; // 左子节点
327 | private Node right; // 右子节点
328 |
329 | public Node(int element) {
330 | this.element = element;
331 | }
332 |
333 | /**
334 | * 以当前节点为根的高度
335 | *
336 | * @return
337 | */
338 | public int height() {
339 | return Math.max(left == null ? 0 : left.height(), right == null ? 0 : right.height()) + 1;
340 | }
341 |
342 | /**
343 | * 当前节点的左子树高度
344 | *
345 | * @return
346 | */
347 | public int leftHeight() {
348 | if (left == null) {
349 | return 0;
350 | }
351 | return left.height();
352 | }
353 |
354 | /**
355 | * 当前节点的右子树高度
356 | *
357 | * @return
358 | */
359 | public int rightHeight() {
360 | if (right == null) {
361 | return 0;
362 | }
363 | return right.height();
364 | }
365 |
366 | /**
367 | * 左旋转(向左旋转)
368 | *
369 | * 以当前节点为树根,当(右子树的高度 - 左子树的高度) > 1时,进行左旋转:
370 | * (1)将当前(根)节点向左下移,成为新的左子节点;并将其右子节点设为原根节点右子树的左子树
371 | * (2)将当前节点的右节点上移,成新的树根(当前节点);并将左子节点指向新的左子节点(原树根)
372 | */
373 | public void leftRotate() {
374 | // 将当前节点向左下移,成为新的左节点
375 | Node newLeftNode = new Node(element);
376 | newLeftNode.left = left;
377 | // 将右子节点设为原根节点右子树的左子树
378 | newLeftNode.right = right.left;
379 |
380 | // 将右节点上移,成为新的树根(当前节点)
381 | element = right.element;
382 | // 将左子节点设为新的左子节点(原树根)
383 | left = newLeftNode;
384 | right = right.right;
385 |
386 | }
387 |
388 | /**
389 | * 右旋转(向右旋转)
390 | *
391 | * 以当前节点为树根,当(左子树的高度 - 右子树的高度) > 1时,进行右旋转:
392 | * (1)将当前(根)节点向右下移,成为新的右子节点;并将其左子节点设为原根节点左子树的右子树
393 | * (2)将当前节点的右节点上移,成为新的树根(当前节点);并将右子节点指向新的右子节点(原树根)
394 | */
395 | public void rightRotate() {
396 | // 将当前节点向右下移,成为新的右子节点
397 | Node newRightNode = new Node(element);
398 | // 将左子节点指向原根节点的左子树的右子树
399 | newRightNode.left = left.right;
400 | newRightNode.right = right;
401 |
402 | // 将左子节点上移,成为新的树根(当前节点)
403 | element = left.element;
404 | left = left.left;
405 | // 将右子节点设为新的右子节点(原树根)
406 | right = newRightNode;
407 | }
408 |
409 | @Override
410 | public int compareTo(Integer o) {
411 | return o.compareTo(element);
412 | }
413 |
414 | @Override
415 | public String toString() {
416 | return "Node{" +
417 | "element=" + element +
418 | '}';
419 | }
420 | }
421 | }
422 |
--------------------------------------------------------------------------------
/java-source-analysis/src/main/java/io/github/gozhuyinglong/reflection/ReflectionTest.java:
--------------------------------------------------------------------------------
1 | package io.github.gozhuyinglong.reflection;
2 |
3 | import org.junit.Test;
4 |
5 | import java.lang.annotation.Annotation;
6 | import java.lang.reflect.*;
7 |
8 | /**
9 | * @author 码农StayUp
10 | * @date 2021/2/2 0002
11 | */
12 | public class ReflectionTest {
13 |
14 | /**
15 | * 获取 Class 类实例的四种方式
16 | */
17 | @Test
18 | public void testClassFor() {
19 |
20 | // 1.通过类实例获取
21 | Person person = new Person();
22 | Class extends Person> clazz1 = person.getClass();
23 | System.out.println("01 - " + clazz1);
24 |
25 | // 2.通过类直接调用class获取
26 | Class clazz2 = Person.class;
27 | System.out.println("02 - " + clazz2);
28 |
29 | // 3.通过Class.forName获取
30 | Class> clazz3 = null;
31 | try {
32 | clazz3 = Class.forName("io.github.gozhuyinglong.reflection.Person");
33 | } catch (ClassNotFoundException e) {
34 | // 当找不到指定类时,会抛出此异常
35 | e.printStackTrace();
36 | }
37 | System.out.println("03 - " + clazz3);
38 |
39 | // 4.通过类加载器获取
40 | ClassLoader classLoader = this.getClass().getClassLoader();
41 | Class> clazz4 = null;
42 | try {
43 | clazz4 = classLoader.loadClass("io.github.gozhuyinglong.reflection.Person");
44 | } catch (ClassNotFoundException e) {
45 | // 当找不到指定类时,会抛出此异常
46 | e.printStackTrace();
47 | }
48 | System.out.println("04 - " + clazz4);
49 |
50 | // hashCode相等,说明这四种方式获取的是同一个实例
51 | System.out.println("05 - " + clazz1.hashCode());
52 | System.out.println("06 - " + clazz2.hashCode());
53 | System.out.println("07 - " + clazz3.hashCode());
54 | System.out.println("08 - " + clazz4.hashCode());
55 |
56 | }
57 |
58 | /**
59 | * 一些特殊的接口、类、关键字
60 | */
61 | @Test
62 | public void testClassOther() {
63 |
64 | // 枚举是一种类
65 | Class clazz1 = PersonEnum.class;
66 | System.out.println("01 - " + clazz1);
67 |
68 | // 注解是一种接口
69 | Class clazz2 = PersonAnnotation.class;
70 | System.out.println("02 - " + clazz2);
71 |
72 | // 数组也属于一个反应 Class 实例的类
73 | Person[] personArray3 = new Person[1];
74 | Class extends Person[]> clazz3 = personArray3.getClass();
75 | System.out.println("03 - " + clazz3);
76 |
77 | // 具有相同元素类型和维数的数组,也具有相同的 Class 实例
78 | Person[] personArray4 = new Person[4];
79 | Class> clazz4 = personArray4.getClass();
80 |
81 | Person[][] personArray5 = new Person[1][];
82 | Class> clazz5 = personArray5.getClass();
83 |
84 | // 两个一维数组的 hashCode 相等,说明是同一实例
85 | System.out.println("04 - " + clazz3.hashCode());
86 | System.out.println("05 - " + clazz4.hashCode());
87 | // 一维数组与二维数组的 hashCode 不相等,说明不是同一实例
88 | System.out.println("06 - " + clazz5.hashCode());
89 |
90 | // 原始 Java 类型和关键字 void 也表示为 Class 实例
91 | Class clazz6 = int.class;
92 | System.out.println("07 - " + clazz6);
93 |
94 | Class clazz7 = double.class;
95 | System.out.println("08 - " + clazz7);
96 |
97 | Class clazz8 = void.class;
98 | System.out.println("09 - " + clazz8);
99 |
100 | }
101 |
102 | /**
103 | * 类
104 | *
105 | * @throws Exception
106 | */
107 | @Test
108 | public void testClass() throws Exception {
109 | Class> clazz = Class.forName("io.github.gozhuyinglong.reflection.Person");
110 |
111 | // 获取该类所在包路径
112 | Package aPackage = clazz.getPackage();
113 | System.out.println("01 - " + aPackage);
114 |
115 | // 获取该类上所有注解
116 | Annotation[] declaredAnnotations = clazz.getDeclaredAnnotations();
117 | for (Annotation temp : declaredAnnotations) {
118 | System.out.println("02 - " + temp);
119 | }
120 |
121 | // 获取类上的修饰符
122 | int modifiers = clazz.getModifiers();
123 | String modifier = Modifier.toString(modifiers);
124 | System.out.println("03 - " + modifier);
125 |
126 | // 获取类名称
127 | String name = clazz.getName();
128 | System.out.println("04 - " + name);
129 | // 获取简单类名
130 | String simpleName = clazz.getSimpleName();
131 | System.out.println("05 - " + simpleName);
132 |
133 | // 获取直属超类
134 | Type genericSuperclass = clazz.getGenericSuperclass();
135 | System.out.println("06 - " + genericSuperclass);
136 |
137 | // 获取直属实现的接口
138 | Type[] genericInterfaces = clazz.getGenericInterfaces();
139 | for (Type temp : genericInterfaces) {
140 | System.out.println("07 - " + temp);
141 | }
142 |
143 | }
144 |
145 | /**
146 | * 构造函数
147 | *
148 | * @throws Exception
149 | */
150 | @Test
151 | public void testConstructor() throws Exception {
152 | Class> clazz = Class.forName("io.github.gozhuyinglong.reflection.Person");
153 |
154 | // 获取一个声明为 public 构造函数实例
155 | Constructor> constructor1 = clazz.getConstructor(String.class, int.class, PersonEnum.class);
156 | System.out.println("01 - " + constructor1);
157 |
158 | // 获取所有声明为 public 构造函数实例
159 | Constructor>[] constructorArray1 = clazz.getConstructors();
160 | for (Constructor> constructor : constructorArray1) {
161 | System.out.println("02 - " + constructor);
162 | }
163 |
164 | // 获取一个声明的构造函数实例
165 | Constructor> constructor2 = clazz.getDeclaredConstructor(String.class);
166 | System.out.println("03 - " + constructor2);
167 |
168 | // 获取所有声明的构造函数实例
169 | Constructor>[] constructorArray2 = clazz.getDeclaredConstructors();
170 | for (Constructor> constructor : constructorArray2) {
171 | System.out.println("04 - " + constructor);
172 | }
173 |
174 | // 根据构造函数创建一个实例
175 | Object o1 = constructor1.newInstance("杨过", 25, PersonEnum.MAN);
176 | System.out.println("05 - " + o1);
177 |
178 | // 将构造函数的可访问标志设为 true 后,可以通过私有构造函数创建实例
179 | constructor2.setAccessible(true);
180 | Object o2 = constructor2.newInstance("小龙女");
181 | System.out.println("06 - " + o2);
182 |
183 | // 获取该构造函数上的所有注解
184 | Annotation[] annotations = constructor1.getDeclaredAnnotations();
185 | for (Annotation annotation : annotations) {
186 | System.out.println("07 - " + annotation);
187 | }
188 |
189 | // 获取该构造函数上的所有参数类型
190 | Type[] genericParameterTypes = constructor1.getGenericParameterTypes();
191 | for (Type genericParameterType : genericParameterTypes) {
192 | System.out.println("08 - " + genericParameterType);
193 | }
194 |
195 | }
196 |
197 | /**
198 | * 属性
199 | *
200 | * @throws Exception
201 | */
202 | @Test
203 | public void testField() throws Exception {
204 |
205 | Class> clazz = Class.forName("io.github.gozhuyinglong.reflection.Person");
206 |
207 | // 获取一个该类或父类中声明为 public 的属性
208 | Field field1 = clazz.getField("hobby");
209 | System.out.println("01 - " + field1);
210 |
211 | // 获取该类及父类中所有声明为 public 的属性
212 | Field[] fieldArray1 = clazz.getFields();
213 | for (Field field : fieldArray1) {
214 | System.out.println("02 - " + field);
215 | }
216 |
217 | // 获取一个该类中声明的属性
218 | Field field2 = clazz.getDeclaredField("name");
219 | System.out.println("03 - " + field2);
220 |
221 | // 获取该类中所有声明的属性
222 | Field[] fieldArray2 = clazz.getDeclaredFields();
223 | for (Field field : fieldArray2) {
224 | System.out.println("04 - " + field);
225 | }
226 |
227 | // 获取该属性上的所有注解
228 | Annotation[] declaredAnnotations = field2.getDeclaredAnnotations();
229 | for (Annotation declaredAnnotation : declaredAnnotations) {
230 | System.out.println("05 - " + declaredAnnotation);
231 | }
232 |
233 | // 获取修饰符
234 | String modifier = Modifier.toString(field2.getModifiers());
235 | System.out.println("06 - " + modifier);
236 |
237 | // 获取属性类型,返回类对象
238 | Class> type = field2.getType();
239 | System.out.println("07 - " + type);
240 | // 获取属性类型,返回Type对象
241 | Type genericType = field2.getGenericType();
242 | System.out.println("08 - " + genericType);
243 |
244 | // 获取属性名称
245 | String name = field2.getName();
246 | System.out.println("09 - " + name);
247 |
248 | }
249 |
250 |
251 | /**
252 | * 方法
253 | *
254 | * @throws Exception
255 | */
256 | @Test
257 | public void testMethod() throws Exception {
258 |
259 | Class> clazz = Class.forName("io.github.gozhuyinglong.reflection.Person");
260 |
261 | // 获取一个该类及父类中声明为 public 的方法,需要指定方法的入参类型
262 | Method method = clazz.getMethod("setName", String.class);
263 | System.out.println("01 - " + method);
264 |
265 | // 获取该类及父类中所有声明为 public 的方法
266 | Method[] methods = clazz.getMethods();
267 | for (Method temp : methods) {
268 | System.out.println("02 - " + temp);
269 | }
270 |
271 | // 获取一个在该类中声明的方法
272 | Method declaredMethod = clazz.getDeclaredMethod("display");
273 | System.out.println("03 - " + declaredMethod);
274 |
275 | // 获取所有在该类中声明的方法
276 | Method[] declaredMethods = clazz.getDeclaredMethods();
277 | for (Method temp : declaredMethods) {
278 | System.out.println("04 - " + temp);
279 | }
280 |
281 | // 获取该方法上的所有注解
282 | Annotation[] declaredAnnotations = method.getDeclaredAnnotations();
283 | for (Annotation temp : declaredAnnotations) {
284 | System.out.println("05 - " + temp);
285 | }
286 |
287 | // 获取修饰符
288 | String modifier = Modifier.toString(method.getModifiers());
289 | System.out.println("06 - " + modifier);
290 |
291 | // 获取返回值类型,返回类对象
292 | Class> returnType = method.getReturnType();
293 | System.out.println("07 - " + returnType);
294 | // 获取返回值类型,返回Type对象
295 | Type genericReturnType = method.getGenericReturnType();
296 | System.out.println("08 - " + genericReturnType);
297 |
298 | // 获取方法名称
299 | String name = method.getName();
300 | System.out.println("09 - " + name);
301 |
302 | // 获取所有入参
303 | Parameter[] parameters = method.getParameters();
304 | for (Parameter temp : parameters) {
305 | System.out.println("10 - " + temp);
306 | }
307 |
308 | }
309 |
310 | /**
311 | * 访问修饰符,以下简称:修饰符
312 | *
313 | * @throws Exception
314 | */
315 | @Test
316 | public void testModifier() throws Exception {
317 | Class> clazz = Class.forName("io.github.gozhuyinglong.reflection.Person");
318 |
319 | // 获取类的修饰符值
320 | int modifiers1 = clazz.getModifiers();
321 | System.out.println("01 - " + modifiers1);
322 |
323 | // 获取属性的修饰符值
324 | int modifiers2 = clazz.getDeclaredField("name").getModifiers();
325 | System.out.println("02 - " + modifiers2);
326 |
327 | // 获取构造函数的修饰符值
328 | int modifiers3 = clazz.getDeclaredConstructor(String.class).getModifiers();
329 | System.out.println("03 - " + modifiers3);
330 |
331 | // 获取方法的修饰符值
332 | int modifiers4 = clazz.getDeclaredMethod("display").getModifiers();
333 | System.out.println("04 - " + modifiers4);
334 |
335 | // 判断修饰符值是否 final 类型
336 | boolean isFinal = Modifier.isFinal(modifiers1);
337 | System.out.println("05 - " + isFinal);
338 |
339 | // 判断修饰符值是否 public 类型
340 | boolean isPublic = Modifier.isPublic(modifiers2);
341 | System.out.println("06 - " + isPublic);
342 |
343 | // 根据修饰符值,获取修饰符标志的字符串
344 | String modifier = Modifier.toString(modifiers1);
345 | System.out.println("07 - " + modifier);
346 | System.out.println("08 - " + Modifier.toString(modifiers2));
347 |
348 | }
349 |
350 | /**
351 | * 参数
352 | *
353 | * @throws Exception
354 | */
355 | @Test
356 | public void testParameter() throws Exception {
357 | Class> clazz = Class.forName("io.github.gozhuyinglong.reflection.Person");
358 |
359 | // 获取构造函数的参数
360 | Constructor> constructor = clazz.getConstructor(String.class, int.class, PersonEnum.class);
361 | Parameter[] parameterArray1 = constructor.getParameters();
362 | for (Parameter temp : parameterArray1) {
363 | System.out.println("01 - " + temp);
364 | }
365 |
366 | // 获取方法的参数
367 | Method method = clazz.getMethod("setName", String.class);
368 | Parameter[] parameterArray2 = method.getParameters();
369 | for (Parameter temp : parameterArray2) {
370 | System.out.println("02 - " + temp);
371 | }
372 |
373 | Parameter parameter = parameterArray1[0];
374 | // 获取参数上的注解
375 | Annotation[] annotationArray = parameter.getAnnotations();
376 | for (Annotation temp : annotationArray) {
377 | System.out.println("02 - " + temp);
378 | }
379 |
380 | // 获取参数名称
381 | String name = parameter.getName();
382 | System.out.println("03 - " + name);
383 |
384 | // 获取参数类型
385 | Type parameterizedType = parameter.getParameterizedType();
386 | System.out.println("04 - " + parameterizedType);
387 | Class> type = parameter.getType();
388 | System.out.println("05 - " + type);
389 |
390 | }
391 |
392 | /**
393 | * 创建对象并执行方法
394 | *
395 | * @throws Exception
396 | */
397 | @Test
398 | public void testInvoke() throws Exception {
399 | Class> clazz = Class.forName("io.github.gozhuyinglong.reflection.Person");
400 |
401 | // 通过Class类的newInstance创建一个实例。(该方法调用无参构造器)
402 | Object o1 = clazz.newInstance();
403 | System.out.println("01 - " + o1.toString());
404 |
405 | // 通过构造函数Constructor类创建一个实例
406 | Constructor> constructor = clazz.getConstructor(String.class, int.class, PersonEnum.class);
407 | Object o2 = constructor.newInstance("杨过", 25, PersonEnum.MAN);
408 | System.out.println("02 - " + o2.toString());
409 |
410 | // 先获取方法,再通过 invoke 方法来调用,第一个参数为实例,后面参数为方法的Parameter
411 | Method method = clazz.getMethod("setName", String.class);
412 | method.invoke(o1, "小龙女");
413 | System.out.println("03 - " + o1.toString());
414 |
415 | // 获取字段,因为 age 字段是私有的,所以将其设置为可访问(不设置会报异常)。并通过 set 方法来赋值
416 | Field field = clazz.getDeclaredField("age");
417 | field.setAccessible(true);
418 | field.set(o1, 28);
419 | System.out.println("04 - " + o1.toString());
420 |
421 | }
422 |
423 |
424 | }
425 |
--------------------------------------------------------------------------------