Skip to content

Commit beb72ed

Browse files
author
yangjingjing
committed
blog
1 parent dac44d8 commit beb72ed

File tree

103 files changed

+12737
-3648
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

103 files changed

+12737
-3648
lines changed

_posts/2015-01-05-Java枚举.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
layout: post
3+
categories: [Java]
4+
description: none
5+
keywords: Java
6+
---
7+
# Java枚举

_posts/2015-01-07-Java反射.md

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
---
2+
layout: post
3+
categories: [Java]
4+
description: none
5+
keywords: Java
6+
---
7+
# Java反射
8+
9+
10+
## 何为反射?
11+
反射(Reflection),是指Java程序具有在 运行期分析类以及修改其本身状态或行为的能力。 通俗点说 就是 通过反射我们可以 动态地 获取一个类的所有属性和方法,还可以操作这些方法和属性。
12+
13+
## 实例的创建
14+
一般我们创建一个对象实例Person zhang = new Person();
15+
虽然是简简单单一句,但JVM内部的实现过程是复杂的:
16+
17+
- 将硬盘上指定位置的Person.class文件加载进内存
18+
- 执行main方法时,在栈内存中开辟了main方法的空间(压栈-进栈),然后在main方法的栈区分配了一个变量zhang。
19+
- 执行new,在堆内存中开辟一个 实体类的 空间,分配了一个内存首地址值
20+
- 调用该实体类对应的构造函数,进行初始化(如果没有构造函数,Java会补上一个默认构造函数)。
21+
- 将实体类的 首地址赋值给zhang,变量zhang就引用了该实体。(指向了该对象)
22+
23+
将class文件加载到内存中具体分为3个阶段:加载、连接、初始化
24+
25+
JVM 的类加载器(你可以理解成一个工具)通过一个类的全限定名来获取该类的二进制字节流,然后将该 class 文件加载到 JVM 的方法区中。
26+
27+
类加载器加载一个 .class 文件到方法区的同时会在堆中生成一个唯一的 Class 对象,这个 Class 包含这个类的成员变量、构造方法以及成员方法。
28+
29+
所以表面上你 new 了一个对象,实际上当 JVM 运行程序的时候,真正帮你创建对象的是该类的 Class 对象。
30+
31+
也就是说反射其实就是 JVM 在运行程序的时候将你创建的所有类都封装成唯一一个 Class 对象。这个 Class 对象包含属性、构造方法和成员方法。你拿到了 Class 对象,也就能获取这三个东西。
32+
33+
你拿到了反射之后(Class)的属性,就能获取对象的属性名、属性类别、属性值,也能给属性设置值。
34+
35+
你拿到了反射之后(Class)的构造方法,就能创建对象。
36+
37+
你拿到了反射之后(Class)的成员方法,就能执行该方法。
38+
39+
而又在 加载阶段,类加载器 会将类对应的.class文件中的二进制字节流读入到内存中,将这个字节流转化为方法区的运行时数据结构,然后在堆区创建一个java.lang.Class对象(类相关的信息),作为对方法区中这些数据的访问入口
40+
41+
然后再通过 类的实例 来执操作 类的方法和属性 ,比如zhang.eat(), zhang.getHeight()等等
42+
43+
如果我们使用反射的话,我们需要拿到该类Person的Class对象,再通过Class对象来操作 类的方法和属性或者创建类的实例
44+
```
45+
Class personClass = Person.class;//这边只是举一个例子,获取class对象的多种方式,本文后面再慢慢道来
46+
Object person = personClass.newInstance();
47+
```
48+
我们可以发现 通过new创建类的实例和反射创建类的实例,都绕不开.class文件 和 Class类的。
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+
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
---
2+
layout: post
3+
categories: [Java]
4+
description: none
5+
keywords: Java
6+
---
7+
# Java源码Class类
8+
9+
##
10+
我们来看下Class类的源码,源码太多了,挑了几个重点:
11+
```
12+
public final class Class<T> implements java.io.Serializable,
13+
GenericDeclaration,
14+
Type,
15+
AnnotatedElement {
16+
private static final int ANNOTATION= 0x00002000;
17+
private static final int ENUM = 0x00004000;
18+
private static final int SYNTHETIC = 0x00001000;
19+
20+
private static native void registerNatives();
21+
static {
22+
registerNatives();
23+
}
24+
25+
/*
26+
* Private constructor. Only the Java Virtual Machine creates Class objects.
27+
* This constructor is not used and prevents the default constructor being
28+
* generated.
29+
*/
30+
private Class(ClassLoader loader) { //私有化的 构造器
31+
// Initialize final field for classLoader. The initialization value of non-null
32+
// prevents future JIT optimizations from assuming this final field is null.
33+
classLoader = loader;
34+
}
35+
...
36+
37+
// reflection data that might get invalidated when JVM TI RedefineClasses() is called
38+
private static class ReflectionData<T> {
39+
volatile Field[] declaredFields;//字段
40+
volatile Field[] publicFields;
41+
volatile Method[] declaredMethods;//方法
42+
volatile Method[] publicMethods;
43+
volatile Constructor<T>[] declaredConstructors;//构造器
44+
volatile Constructor<T>[] publicConstructors;
45+
// Intermediate results for getFields and getMethods
46+
volatile Field[] declaredPublicFields;
47+
volatile Method[] declaredPublicMethods;
48+
volatile Class<?>[] interfaces;//接口
49+
50+
// Value of classRedefinedCount when we created this ReflectionData instance
51+
final int redefinedCount;
52+
53+
ReflectionData(int redefinedCount) {
54+
this.redefinedCount = redefinedCount;
55+
}
56+
}
57+
...
58+
//注释数据
59+
private volatile transient AnnotationData annotationData;
60+
61+
private AnnotationData annotationData() {
62+
while (true) { // retry loop
63+
AnnotationData annotationData = this.annotationData;
64+
int classRedefinedCount = this.classRedefinedCount;
65+
if (annotationData != null &&
66+
annotationData.redefinedCount == classRedefinedCount) {
67+
return annotationData;
68+
}
69+
// null or stale annotationData -> optimistically create new instance
70+
AnnotationData newAnnotationData = createAnnotationData(classRedefinedCount);
71+
// try to install it
72+
if (Atomic.casAnnotationData(this, annotationData, newAnnotationData)) {
73+
// successfully installed new AnnotationData
74+
return newAnnotationData;
75+
}
76+
}
77+
}
78+
...
79+
```
80+
Class类的构造方法是private, 只有JVM能创建Class实例 ,我们开发人员 是无法创建Class实例的,JVM在构造Class对象时,需要传入一个 类加载器 。
81+
82+
类也是可以用来存储数据的,Class类就像 普通类的模板 一样,用来保存“类所有相关信息”的类 。
83+
84+
85+
86+
87+
88+
89+
90+
91+
92+
93+
94+
95+
96+
97+
98+
99+
100+
101+
102+
103+
104+
105+
106+
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
layout: post
3+
categories: [Java]
4+
description: none
5+
keywords: Java
6+
---
7+
# Java常见错误
8+
9+
## String.valueof(e)
10+
```
11+
list.stream()
12+
.filter(Objects::nonNull)
13+
.map(e->String.valueof(e))
14+
.collect(Collectors.groupingBy(Function.identity(),
15+
Collectors.counting()
16+
));
17+
```
18+
String.valueof会转为"null"。然后filter 就没有作用导致脏数据。

_posts/2015-01-14-Stream分组.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,5 +133,25 @@ public class TestGroupingBy {
133133
```
134134
groupingMap数据仅仅只有一层,但是其键值Key却是一个List,里面包含了分组字段的值。由于Map只有一层,用该方式分组的结果,对于我们业务也是比较友好,代码里对数据处理起来也是比较方便的。
135135

136+
## List转Map
137+
第一种(会出现键重复异常):
138+
```
139+
//以id为主键转为map
140+
Map<Long, User> map = list.stream().collect(Collectors.toMap(User::getId,Function.identity()));
141+
```
142+
第二种(针对第一种方法会出现情况):
143+
```
144+
//给出key重复时,使用哪个key作为主键,以下代码中的(key1, key2) -> key2)代表key1和key2键重复时返回key2做主键
145+
Map<Long, User> map = list.stream().collect(Collectors.toMap(User::getId, Function.identity(), (key1, key2) -> key2));
146+
```
147+
第三种(只返回对象里某个属性时):
148+
```
149+
// 不想返回对象,只返回对象里某个属性时 采用这种方式
150+
Map<Long, String> map = list.stream().collect(Collectors.toMap(User::getId, User::getAge, (key1, key2) -> key2));
151+
```
152+
第四种(以某个属性分组):
153+
```
154+
Map<Integer, List> map = list.stream().collect(Collectors.groupingBy(User::getId));
155+
```
136156

137157

_posts/2015-05-24-Go开源beego.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
layout: post
3-
categories: Go
3+
categories: [Go]
44
description: none
55
keywords: Go
66
---

_posts/2015-07-01-Scala基础入门.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
layout: post
3-
categories: Scala
3+
categories: [Scala]
44
description: none
55
keywords: Scala
66
---

0 commit comments

Comments
 (0)