Skip to content

Commit 98ecae4

Browse files
author
yangjingjing
committed
init blog
1 parent 2bdb41a commit 98ecae4

File tree

74 files changed

+4417
-856
lines changed

Some content is hidden

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

74 files changed

+4417
-856
lines changed

_posts/2015-01-04-Java面向对象final.md

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ keywords: Java
99
## final关键字
1010
final关键字的中文含义是“最终的”。在Java中,final关键字可以用来修饰**类、方法和变量(包括成员变量和局部变量)**
1111

12+
一旦你将引用声明作final,你将不能改变这个引用了,编译器会检查代码,如果你试图将变量再次初始化的话,编译器会报编译错误。
13+
1214
### final类
1315
当用final修饰一个类时,表明这个类不能被继承,也不能产生子类。最常见是就是String类,任何类都无法继承它。
1416

@@ -18,19 +20,30 @@ public final class String
1820

1921
}
2022
```
21-
如果一个类你永远不会让他被继承(子类继承往往可以重写父类的方法和改变父类属性,会带来一定的安全隐患),就可以用final进行修饰。注意,final类中的成员变量可以根据需要设置为final,但是它的所有成员方法会被隐式地指定为final方法。在使用final修饰类的时候,要注意谨慎选择,除非这个类真的在以后不会用来继承或者出于安全的考虑,尽量不要将类设计为final类。
23+
如果一个类你永远不会让他被继承(子类继承往往可以重写父类的方法和改变父类属性,会带来一定的安全隐患),就可以用final进行修饰。
24+
25+
注意,final类中的成员变量可以根据需要设置为final,但是它的所有成员方法会被隐式地指定为final方法。在使用final修饰类的时候,要注意谨慎选择,除非这个类真的在以后不会用来继承或者出于安全的考虑,尽量不要将类设计为final类。
2226

2327
### final方法
2428
当父类的方法被final修饰的时候,子类不能重写父类的该方法,比如在Object中,getClass()方法就是final的,我们就不能重写该方法。
29+
2530
```java
2631
public class Object {
2732
public final native Class<?> getClass();
2833
}
2934
```
35+
3036
如果想禁止该方法在子类中被重写的,可以设置该方法为为final。注意:因为重写的前提是子类可以从父类中继承此方法,如果父类中final修饰的方法同时访问控制权限为private,将会导致子类中不能直接继承到此方法,此时子类中就可以定义相同的方法名和参数。
3137

38+
第二个原因是效率,final方法比非final方法要快,因为在编译的时候已经静态绑定了,不需要在运行时再动态绑定。
39+
(注:类的private方法会隐式地被指定为final方法)
40+
3241
### final变量
33-
final修饰变量表示这个变量一旦赋值就不能修改。需要注意,当final修饰一个基本数据类型时,表示该基本数据类型的值一旦在初始化后便不能发生变化;如果final修饰一个引用类型时,则在对其初始化之后便不能再让其指向其他对象了,但该引用所指向的对象的内容是可以发生变化的,final只保证这个引用类型变量所引用的地址不会发生改变,即一直引用这个对象,但这个对象属性是可以改变的。
42+
final成员变量表示常量,只能被赋值一次,赋值后值不再改变(final要求地址值不能改变)
43+
44+
当final修饰一个基本数据类型时,表示该基本数据类型的值一旦在初始化后便不能发生变化;如果final修饰一个引用类型时,则在对其初始化之后便不能再让其指向其他对象了,但该引用所指向的对象的内容是可以发生变化的。本质上是一回事,因为引用的值是一个地址,final要求值,即地址的值不发生变化。
45+
46+
final修饰一个成员变量(属性),必须要显示初始化。这里有两种初始化方式,一种是在变量声明的时候初始化;第二种方法是在声明变量的时候不赋初值,但是要在这个变量所在的类的所有的构造函数中对这个变量赋初值。
3447

3548
final关键字修饰的变量可以分为属性、局部变量和形参。无论修饰哪种变量,其含义都是相同的,即变量一旦赋值就不能改变。
3649

@@ -116,6 +129,29 @@ public static void main(String[] args) {
116129
```
117130
根据上面对宏变量的分析,我们知道finalWorld2和finalWorld4是属于宏变量,因此后续程序会直接使用其值“hello”来代替finalWorld2和finalWorld4。因此hw2和hw4等同于"hello world",所以hw=hw2=hw4。
118131

132+
## final使用总结
133+
- final关键字提高了性能。JVM和Java应用都会缓存final变量。
134+
- final变量可以安全的在多线程环境下进行共享,而不需要额外的同步开销。
135+
- 使用final关键字,JVM会对方法、变量及类进行优化。
136+
137+
## 关于final的重要知识点
138+
- final关键字可以用于成员变量、本地变量、方法以及类。
139+
- final成员变量必须在声明的时候初始化或者在构造器中初始化,否则就会报编译错误。
140+
- 你不能够对final变量再次赋值。
141+
- 本地变量必须在声明时赋值。
142+
- 在匿名类中所有变量都必须是final变量。
143+
- final方法不能被重写。
144+
- final类不能被继承。
145+
- final关键字不同于finally关键字,后者用于异常处理。
146+
- final关键字容易与finalize()方法搞混,后者是在Object类中定义的方法,是在垃圾回收之前被JVM调用的方法。
147+
- 接口中声明的所有变量本身是final的。
148+
- final和abstract这两个关键字是反相关的,final类就不可能是abstract的。
149+
- final方法在编译阶段绑定,称为静态绑定(static binding)。
150+
- 没有在声明时初始化final变量的称为空白final变量(blank final variable),它们必须在构造器中初始化,或者调用this()初始化。不这么做的话,编译器会报错“final变量(变量名)需要进行初始化”。
151+
- 将类、方法、变量声明为final能够提高性能,这样JVM就有机会进行估计,然后优化。
152+
- 按照Java代码惯例,final变量就是常量,而且通常常量名要大写。
153+
- 对于集合对象声明为final指的是引用不能被更改,但是你可以向其中增加,删除或者改变内容。
154+
119155
## final域重排序规则
120156
然而在多线程的层面,final也有其自己的内存语义。主要体现在final域的重排序上,下面我们来介绍final的重排序规则
121157

_posts/2015-01-06-Java注解.md

Lines changed: 308 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,308 @@
1+
---
2+
layout: post
3+
categories: [Java]
4+
description: none
5+
keywords: Java
6+
---
7+
# Java注解
8+
9+
## 什么是注解?
10+
注解(Annotation),也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。
11+
12+
相信很多学过spring等框架的同学对注解一定不陌生吧!比如@Service,@Repository,@Autowired等等。就算没有学过框架,但凡你只要学了java基础,你都会接触到注解。比如一个子类继承父类的方法,该方法前面会有@Override,这个其实就是注解!
13+
14+
## 如何声明注解?
15+
使用@interface关键字就能声明一个注解。如下例:
16+
```
17+
public @interface TestAnno {
18+
19+
}
20+
```
21+
22+
## 如何声明注解的生命周期和作用域?
23+
```
24+
@Target(ElementType.FIELD) //作用域 FIELD表示只能作用在字段中
25+
@Retention(RetentionPolicy.RUNTIME) //生命周期 RUNTIME表示运行时有效
26+
@Documented //让它定制文档化功能,使用使用此注解时必须设置RetentionPolicy为RUNTIME
27+
@Inherited //让它允许继承,可作用到子类
28+
public @interface Column {
29+
/**
30+
* 属性变量只能声明无参无异常的,当只有一个属性时,属性名称为value,
31+
*/
32+
String value();
33+
}
34+
```
35+
ElementType中的所有值都可以作为@Column的作用域,而且作用域可以同时有多个值比如@Target(ElementType.TYPE,ElementType.FIELD)表示该注解可以作用在类上,也能作用在字段上。
36+
37+
RetentionPolicy的取值有三个,分别是SOURCE,CLASS,RUNTIME。分别表示源码注解,注解会保留在源码中,在编译和运行时无效。编译注解,注解会保留在class文件中,编译时会识别,运行时不识别。运行时注解,注解会保留到class文件中,同时运行时也会被识别。
38+
39+
## 注解的应用
40+
注解的应用十分广泛,这里只展示一小个方面来说明注解的使用原理。当我们使用数据库查询数据时,大多数时候需要我们自己来写sql语句,当我们的逻辑比较多,较复杂时,会显得非常不方便。下面将使用自定义注解实现自动拼接sql,然后自动封装查询结果
41+
42+
首先自定义两个注解
43+
```java
44+
@Target(ElementType.FIELD) //作用域 FIELD表示只能作用在字段中
45+
@Retention(RetentionPolicy.RUNTIME) //生命周期 RUNTIME表示运行时有效
46+
public @interface Column {
47+
/**
48+
* 属性变量只能声明无参无异常的,当只有一个属性时,属性名称为value
49+
*/
50+
String value();
51+
}
52+
```
53+
54+
```java
55+
@Target(ElementType.TYPE) //作用域 TYPE表示只能作用在类中
56+
@Retention(RetentionPolicy.RUNTIME)//生命周期 RUNTIME表示运行时有效
57+
public @interface Table {
58+
/**
59+
* 属性变量只能是无参无异常的,当只有一个属性时,属性名称为value
60+
*/
61+
String value();
62+
}
63+
```
64+
65+
创建一个javaBean
66+
```
67+
@Table("USER")
68+
public class User implements java.io.Serializable {
69+
70+
private static final long serialVersionUID = 1L;
71+
72+
private int id;
73+
74+
@Column("USER_ID")
75+
private String userId; //用户ID
76+
77+
@Column("USER_NAME")
78+
private String userName; //用户名称
79+
80+
@Column("PASSWORD")
81+
private String password; //用户密码
82+
83+
@Column("SEX")
84+
private String sex; //用户性别
85+
86+
@Column("EMAIL")
87+
private String email; //电子邮件
88+
89+
@Column("PHONE")
90+
private String phone; //联系电话
91+
92+
@Column("BIRTHDAY")
93+
private Date birthday; //出生日期
94+
95+
@Column("ADDRESS")
96+
private String address; //家庭住址
97+
98+
@Column("ACTIVE_FLAG")
99+
private int activeFlag=1; //用户活跃标志:0 删除,1 活跃
100+
101+
102+
public String getUserId() {
103+
return userId;
104+
}
105+
public void setUserId(String userId) {
106+
this.userId = userId;
107+
}
108+
public String getUserName() {
109+
return userName;
110+
}
111+
public void setUserName(String userName) {
112+
this.userName = userName;
113+
}
114+
public String getPassword() {
115+
return password;
116+
}
117+
public void setPassword(String password) {
118+
this.password = password;
119+
}
120+
public String getSex() {
121+
return sex;
122+
}
123+
public void setSex(String sex) {
124+
this.sex = sex;
125+
}
126+
public String getEmail() {
127+
return email;
128+
}
129+
public void setEmail(String email) {
130+
this.email = email;
131+
}
132+
public String getPhone() {
133+
return phone;
134+
}
135+
public void setPhone(String phone) {
136+
this.phone = phone;
137+
}
138+
public Date getBirthday() {
139+
return birthday;
140+
}
141+
public void setBirthday(Date birthday) {
142+
this.birthday = birthday;
143+
}
144+
public String getAddress() {
145+
return address;
146+
}
147+
public void setAddress(String address) {
148+
this.address = address;
149+
}
150+
public int getActiveFlag() {
151+
return activeFlag;
152+
}
153+
public void setActiveFlag(int activeFlag) {
154+
this.activeFlag = activeFlag;
155+
}
156+
public int getId() {
157+
return id;
158+
}
159+
public void setId(int id) {
160+
this.id = id;
161+
}
162+
163+
}
164+
```
165+
166+
创建一个JdbcUtil的工具类,使用的是c3p0连接池
167+
```
168+
public class JdbcUtil {
169+
170+
private static ComboPooledDataSource dataSource = new ComboPooledDataSource();
171+
172+
private static Connection getConnection() {
173+
Connection connection = null;
174+
try {
175+
connection = dataSource.getConnection();
176+
} catch (SQLException e) {
177+
e.printStackTrace();
178+
}
179+
return connection;
180+
}
181+
@SuppressWarnings({ "unchecked", "rawtypes" })
182+
public static List<Object> query(Object o) {
183+
Class c = o.getClass();//获取类对象
184+
StringBuffer sb = new StringBuffer();
185+
boolean isExist = c.isAnnotationPresent(Table.class);//判断c中是否存在注解
186+
String tableName = null;
187+
if (isExist) {
188+
//获取表名
189+
Table table = (Table)c.getAnnotation(Table.class);
190+
tableName = table.value();
191+
sb.append("select * from ").append(tableName).append(" where 1=1");
192+
}
193+
Field[] fields = c.getDeclaredFields();
194+
//遍历字段名
195+
for (Field field:fields) {
196+
//判断该字段是否存在注解
197+
if (field.isAnnotationPresent(Column.class)) {
198+
//获取字段名
199+
Column column = field.getAnnotation(Column.class);
200+
String columnName = column.value();
201+
//获取字段值
202+
String fieldName = field.getName();
203+
String getMethodName = "get"+fieldName.substring(0, 1).toUpperCase()+fieldName.substring(1);
204+
Object fieldValue = null;
205+
try {
206+
fieldValue = c.getMethod(getMethodName).invoke(o);
207+
} catch (Exception e) {
208+
e.printStackTrace();
209+
}
210+
//拼接sql
211+
if (fieldValue!=null) {
212+
sb.append(" and ").append(columnName).append("=");
213+
if (fieldValue instanceof String) {
214+
sb.append("'").append(fieldValue).append("'");
215+
}else if (fieldValue instanceof Integer) {
216+
sb.append(fieldValue);
217+
}
218+
}
219+
}
220+
}
221+
String sql = sb.toString();
222+
Connection connection = null;
223+
PreparedStatement preparedStatement = null;
224+
ResultSet rs = null;
225+
try {
226+
connection = getConnection();
227+
preparedStatement = connection.prepareStatement(sql);
228+
rs = preparedStatement.executeQuery();
229+
ResultSetMetaData rMetaData = rs.getMetaData();//获取元数据对象
230+
List<Object> list = new ArrayList<Object>();
231+
while (rs.next()) {
232+
Object object = c.newInstance();//通过类对象获取实例对象
233+
for (int i = 1; i <= rMetaData.getColumnCount(); i++) {
234+
Object value = rs.getObject(i);//获取该列的值
235+
for (int j = 0; j < fields.length; j++) {
236+
if (fields[j].getName().equalsIgnoreCase(rMetaData.getColumnName(i).replace("_", ""))) {
237+
fields[j].setAccessible(true);//私有变量,其它对象不具有访问权,故设置可访问标志为true,给fields[j]提供权限
238+
fields[j].set(object, value);
239+
fields[j].setAccessible(fields[j].isAccessible());//还原可访问标志
240+
}
241+
}
242+
}
243+
list.add(object);
244+
}
245+
return list;
246+
} catch (Exception e) {
247+
e.printStackTrace();
248+
}finally {
249+
close(connection, preparedStatement, rs);
250+
}
251+
return null;
252+
}
253+
254+
private static void close(Connection connection,PreparedStatement preparedStatement,ResultSet resultSet) {
255+
try {
256+
if (connection!=null) {
257+
connection.close();
258+
}
259+
if (preparedStatement!=null) {
260+
preparedStatement.close();
261+
}
262+
if (resultSet!=null) {
263+
resultSet.close();
264+
265+
}
266+
} catch (Exception e) {
267+
e.printStackTrace();
268+
}
269+
}
270+
}
271+
```
272+
在该工具类中,query(Object o)方法就是通过反射的方式来解析注解,获取注解中的值,然后进行相应的处理
273+
274+
写个测试类来验证一下
275+
```java
276+
public class Test {
277+
@org.junit.Test
278+
public void test1() {
279+
User user = new User();
280+
user.setUserName("tom352");
281+
List<Object> list = JdbcUtil.query(user);
282+
List<User> userList = new ArrayList<User>();
283+
if (list!=null && list.size()>0) {
284+
for (Object object : list) {
285+
userList.add((User)object);
286+
}
287+
}
288+
if (userList!=null && userList.size()>0) {
289+
System.out.println(userList.get(0));
290+
}
291+
}
292+
}
293+
```
294+
295+
296+
297+
298+
299+
300+
301+
302+
303+
304+
305+
306+
307+
308+

_posts/2015-01-12-Java网络编程.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -282,8 +282,7 @@ public class ServerSocketDemo {
282282
in = new BufferedReader(new InputStreamReader(socket
283283
.getInputStream()));
284284
String message = in.readLine();
285-
System.out.println("接收到客户端" + counter + "发送的消
286-
息:" + message);
285+
System.out.println("接收到客户端" + counter + "发送的消息:" + message);
287286
in.close();
288287
socket.close();
289288
counter++;

_posts/2015-01-30-Java源码.md

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

0 commit comments

Comments
 (0)