Commons BeanUtils 提供了對 JavaBean 屬性的高層封裝,支援屬性獲取/設置、對象淺拷貝、Map 填充 Bean、動態 Bean(無需預定義類)等功能。官網:https://commons.apache.org/beanutils/。
package demo.bean;
import java.util.*;
public class Company {
private String name;
private Map<String, String> address = new HashMap<>();
private String[] otherInfo;
private List<String> product = new ArrayList<>();
private List<String> employee = new ArrayList<>();
private Map<String, String> telephone = new HashMap<>();
// Getter/Setter 略...
}
Company c = new Company();
c.setName("Lucy");
System.out.println(BeanUtils.getProperty(c, "name")); // Lucy
Map<String, String> tel = new HashMap<>();
tel.put("1", "234-222-1222211");
BeanUtils.setProperty(c, "telephone", tel);
System.out.println(c.getTelephone().get("1")); // 234-222-1222211
Company src = new Company();
src.setName("Lucy");
Company dest = new Company();
BeanUtils.copyProperties(dest, src); // 僅複製可讀寫屬性,同名同類型
System.out.println(BeanUtils.getProperty(dest, "name")); // Lucy
⚠️ 注意:copyProperties 執行淺拷貝,集合、Map、自定義對象屬性會共享引用。修改副本的集合內容會影響原對象。深拷貝需自行實現或使用序列化/第三方庫。
Map<String, String> map = new HashMap<>();
map.put("name", "Lucy");
Company c = new Company();
BeanUtils.populate(c, map); // 鍵名匹配屬性名,自動類型轉換
System.out.println(c.getName()); // Lucy
無需定義類,運行時動態添加屬性,支援巢狀、索引屬性:
LazyDynaMap dyn = new LazyDynaMap();
dyn.set("foo", "bar");
dyn.set("customer", "title", "Mr"); // 巢狀屬性 customer.title
dyn.set("address", 0, "address1"); // 索引屬性 address[0]
System.out.println(dyn.get("address", 0)); // address1
Map<, > backingMap = dyn.getMap(); // 獲取底層 Map
System.out.println(backingMap);
關鍵屬性控制:
setReturnNull(true):獲取不存在屬性返回 null(默認 false 會自動創建)。setRestricted(true):鎖定結構,禁止增刪改屬性(默認 false)。適合將動態 Bean 傳遞到表現層前鎖定結構,防止誤修改。| 特性 | BeanUtils | PropertyUtils |
|---|---|---|
| 類型轉換 | ✅ 自動轉換(字符串→基本類型等) | ❌ 不轉換,類型必須精確匹配 |
| 性能 | 較慢(轉換開銷) | 快(無轉換邏輯) |
| 適用場景 | Web 表單綁定、配置映射等需類型轉換處 | 高性能內部屬性複製、類型已知場景 |
若需自定義轉換邏輯,實現 org.apache.commons.beanutils.Converter 接口並註冊:ConvertUtils.register(converter, targetClass)。
BeanUtils 是 JavaBean 元編程的利器,特別適合框架開發、表單綁定、配置映射等場景。善用 LazyDynaMap 可實現極靈活的動態數據結構,但需注意淺拷貝陷阱與類型轉換性能權衡。