Java 強化
Java筆記目錄可以點這裏: Java強化筆記
代碼規範(包、類、接口、方法、變量、常量名)
爲什麼要有編碼規範(Why Have Code Conventions)?
- 一個軟件的生命週期中,80%的花費在於維護;
- 幾乎沒有任何一個軟件,在其整個生命週期中,均由最初的開發人員來維護;
- 編碼規範可以改善軟件的可讀性,可以讓程序員儘快而徹底地理解新的代碼;
- 如果你將源碼作爲產品發佈,就需要確任它是否被很好的打包並且清晰無誤;
- 不規範,無高薪!
包名:標識符規範,全小寫字母。
- 域名倒寫.模塊名稱.組件名;
com.wolfcode.crm.util;
cn.wolfcode._01_review;
類名:標識符規範,首字母大寫,駝峯命名法,不要用拼音和拼音縮寫。
Employee
EmployeeAdvancedSetting
接口名:副詞、名詞,習慣性以 I
開頭。
IEmployeeDAO
IUSB
方法名:動詞,首字母小寫,駝峯表示法。
sayHello
saveEmployee
變量名:名詞,首字母小寫,駝峯表示法。
username
password
bornDate
常量名:全大寫字母,單詞之間使用下劃線隔開。
MAX_VALUE
NOT_FOUND
知識點回顧 - 主板加載通信組件案例
面向接口編程 + 集合 + 匿名內部類
聲明一個 IUSB
接口作爲規範:
// USB規範
public interface IUSB {
void swapData();
}
創建一個實現該規範的類 Mouse
:
public class Mouse implements IUSB {
public void swapData() {
System.out.println("鼠標在移動");
}
}
創建主板類 MotherBoard
:
import java.util.HashMap;
import java.util.Map;
public class MotherBoard {
// 存儲安裝的USB設備對象
private Map<String, IUSB> plugins = new HashMap<>();
// 將配件插在主板上
public void install(String name, IUSB usb) {
plugins.put(name, usb);
}
// 從主板上卸載指定的配件
public void uninstall(String name) {
plugins.remove(name);
}
// 主板通信, 讓每個配件都工作
public void doWork() {
for (IUSB usb : plugins.values()) {
usb.swapData();
}
}
}
用來啓動項目的類 App
:
public class App {
public static void main(String[] args) {
// 主板對象
MotherBoard board = new MotherBoard();
// 鼠標對象
Mouse mouse = new Mouse();
// 安裝配件
board.install("mouse", mouse);
// 使用匿名內部類, 安裝打印接對象
board.install("print", new IUSB() {
@Override
public void swapData() {
System.out.println("打印......");
}
});
// 調用主板的通信
board.doWork();
System.out.println("-----------------------");
}
}
鼠標在移動
打印......
-----------------------
加載資源文件 + 反射
上面的一系列操作是很常規的面向接口編程,接下來重點來了!!!如果我們要添加一個鍵盤類 Keyboard
要怎麼做,新建一個 Keyboard
類,然後在 App.java
中 new
了,再進行操作嗎?這樣還是有點麻煩了,可以利用 加載資源文件 + 反射 真正實現解放雙手。。
首先創建一個 資源文件夾(必須是 resource folder,它會在編譯時將裏面的文件放到項目的 path 路徑),在裏面引用 properties
文件:
# key = value
mouse = com.yusael._01_review.Mouse
此時目錄是這樣的:
來到 MotherBoard
,使用靜態代碼塊加載資源文件,並通過反射創建對象:
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
public class MotherBoard {
// 存儲安裝的USB設備對象
private static Map<String, IUSB> plugins = new HashMap<>();
//-----------------------靜態代碼快加載資源文件-------------------------
static {
Properties p = new Properties();
// 從classpath的根路徑去加載plugins.properties文件
try (InputStream is = Thread.currentThread()
.getContextClassLoader()
.getResourceAsStream("plugins.properties"))
{
p.load(is);
// 讀取properties文件, 創建USB組件對象
Set<Entry<Object, Object>> entrys = p.entrySet();
for (Entry<Object, Object> entry : entrys) {
// 資源文件中讀取到的類名
String className = entry.getValue().toString();
// 通過反射利用類名創建對象
IUSB usbObject = (IUSB)Class.forName(className).newInstance();
plugins.put(entry.getKey().toString(), usbObject);
}
} catch (Exception e) {
e.printStackTrace();
}
}
//-------------------------------------------------------------------
// 將配件插在主板上
public void install(String name, IUSB usb) {
plugins.put(name, usb);
}
// 從主板上卸載指定的配件
public void uninstall(String name) {
plugins.remove(name);
}
// 主板通信, 讓每個配件都工作
public void doWork() {
for (IUSB usb : plugins.values()) {
usb.swapData();
}
}
}
此時 APP
中的代碼將變得十分簡潔,我們無需再手動創建配件對象再調用主板的 install
,我們只需要維護好配置文件 plugins.properties
中的內容即可。
比如,我們寫一個鍵盤類 Keyboard
:
public class Keyboard implements IUSB{
@Override
public void swapData() {
System.out.println("鍵盤在跳舞");
}
}
我們只需要將它添加到配置文件中即可。
# key=value
mouse = com.yusael._01_review.Mouse
keyboard = com.yusael._01_review.Keyboard
APP
中的代碼是不需要動的。
public class App {
public static void main(String[] args) {
// 主板對象,
MotherBoard board = new MotherBoard();
// 調用主板的通信
board.doWork();
System.out.println("-----------------------");
}
}
鍵盤在跳舞
鼠標在移動
-----------------------
JavaBean 規範
JavaBean 是一種JAVA語言寫成的可重用組件(類),必須遵循一定的規範:
- 類必須使用
public
修飾 - 必須保證有公共無參數構造器
- 包含了屬性的操作手段(
getter
,setter
)
分類:
- 複雜:UI,比如
Button
、Panel
、Window
類 - 簡單:
domain
、dao
、service
組件、封裝數據、操作數據庫、邏輯運算等
成員:
- 方法:
Method
- 事件:
event
- 屬性:
property
屬性:
attribute
:表示狀態,Java中沒有該概念,很多人把 字段(Field) 稱之爲 屬性(attribute)property
:表示狀態,但是不是字段,是字段的操作方法(getter
/setter
)決定的
框架中使用的大多是是屬性。
設置字段值:writeMethod: setter
方法:
public void setXxx(數據類型 變量){
賦值操作;
}
若:setName
----> 屬性:name
若:setUserName
----> 屬性:userName
若:setISBN
----> 屬性:ISBN
獲取字段值:readMethod: getter
方法:
public 數據類型 getXxx(){
return 結果值;
}
若:getName
----> 屬性:name
若:getUserName
----> 屬性:userName
若:getISBN
----> 屬性:ISBN
若:數據類型是 boolean
,則不叫 get 方法,而是is方法,如:isEmpty
標準的屬性:一般提供字段,Eclipse 生成 getter/setter
,字段和屬性同名
是否需要同時提供 getter/setter
:
public class User{
private String firstName; // 名
private String lastName; // 性別
//在數據庫只需要存儲全名
public void setFullName(String fullName){}
}
面試題:說說 JavaBean 和 EJB 的區別。
Lombok 工具
一、Lombok 是什麼
Lombok 是一款小巧的代碼生成工具。官方網址:http://projectlombok.org/
Lombok 主要特性有:自動生成默認的 getter/setter
方法、自動化的資源管理(通過@Cleanup
註解)及註解驅動的異常處理等。目前在國外廣泛應用。
Lombok 它和 jquery 一樣,目標是讓程序員寫更少的代碼,以及改進一些原始語法中不盡人意的地方。Lombok 能做到這一點。既不是用 annotations process,也不是用反射。而是直接黑到了編譯過程中。所以對運行效率沒有任何影響,我們可以通過反編譯 class 文件進行驗證。
二、爲何項目中要引入 Lombok
- 提高開發效率
- 使代碼直觀、簡潔、明瞭、減少了大量冗餘代碼(一般可以節省60%-70%以上的代碼)
- 極大減少了後期維護成本
- 修改變量名不需要再手動修改
getter/setter
三、使用 Lombok
5. 給 Eclipse 安裝插件,識別語法
6. 在項目中引入 lombok 包
7. 使用其中的註解(標籤)
import lombok.Getter;
import lombok.Setter;
@Getter@Setter
public class Person {
private Long id;
private String name;
private Integer age;
}
Ctrl + O 可以看到當前類的字段和方法:getter/setter
已經存在。
內省機制(Introspector)
內省機制作用:查看和操作 JavaBean 中的屬性
- 獲取 JavaBean 中的每一個屬性名/屬性類型
- 通過 getter 方法獲取屬性值;通過 setter 方法給屬性設置值
首先創建一個類 User
:
public class User {
private String name;
private int age;
private boolean man;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public boolean isMan() {
return man;
}
public void setMan(boolean man) {
this.man = man;
}
}
下面是一個關於內省機制的例子:
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
// 內省機制: 操作User類值的屬性
public class IntrospectorDemo {
public static void main(String[] args) throws Exception {
// 1:獲取JavaBean的描述對象
BeanInfo beanInfo = Introspector.getBeanInfo(User.class, Object.class);
User u = User.class.newInstance();
// 2:獲取JavaBean中的屬性的描述器
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
System.out.println(u); // 證明是同一個對象
for (PropertyDescriptor pd : pds) {
// 獲取當前屬性的名稱
System.out.println("屬性名 = " + pd.getName());
// 獲取當前屬性的getter方法
System.out.println("getter : " + pd.getReadMethod());
// 獲取當前屬性的setter方法
System.out.println("setter : " + pd.getWriteMethod());
System.out.println("--------------------------------");
if ("name".equals(pd.getName())) {
Method setter = pd.getWriteMethod(); // 獲取方法
setter.invoke(u, "Jack"); // 調用方法
}
}
System.out.println(u);
}
}