Java 泛型代码 - 反射的力量






3.35/5 (7投票s)
Java 的反射使程序能够自动展开简单的接口,从而创建自动数据对象。
引言
每当要编写应用程序时,将其分解为小块是一个好主意。 任何应用程序的最小部分可能都是数据对象,或 Java 中的简单 Bean。 Java Bean 是简单的 Java 类,具有独特的外观和行为。 它们最简单的目的是包含数据,并且通过拥有属性来实现此目的。 每个属性实际上是一个包含/引用实际数据的数据成员,以及一对方法:getter 方法和 setter 方法。 因此,描述一个人的最简单的数据 Bean 可以这样表示
public interface Person {
// Getter method for FirstName property..
public String getFirstName();
// Setter method for FirstName property..
public void setFirstName(String name);
// Getter method for LastName property..
public String getLastName();
// Setter method for LastName property..
public void setLastName(String name);
// Getter method for Age property..
public int getAge();
// Setter method for Age property..
public void setAge(int age);
}
您的第一个反应可能是,“数据成员在哪里?”,或者“为什么你使用接口而不是类?” 并且您完全有理由提出这两个重要问题中的任何一个。 将事物分解成小块的全部想法是创建一个 API,在参与代码设计和开发的所有各方都同意后,不需要更改。 只有这样,我们才应该生成代码来支持和使用这些 API。 但是,在开发 API 的第一阶段,有时您需要添加属性、更改属性或可能将一个全新的 Bean 引入系统。 如果您的 Bean 实际上不支持其属性,则测试您的 API 是不可能的,因此您必须实际实现某种基本 Bean,或者我称之为 Data-Bean。
在本文中,我将使用 Java 的反射来处理 Data-Bean 的自动化,而无需编写比前面提到的接口或更像接口的代码更多的代码。
背景
本文中的代码使用了我在之前一篇题为“Java 泛型代码 - 反射,简单的方式”的文章中描述的Arguments
类,尽管Arguments
类包含在提供的源代码中,但我建议您阅读我关于反射的文章,以便更容易理解我的DataBeanProxy
类。
代码是如何组织的
只需运行 dev.easyref.tester.DemoApplication
类或双击提供的 JAR 文件。 类结构如下
包 | 源文件 | 目的 |
dev.easyref.tester |
DemoApplication | 演示程序的主类。 |
dev.easyref.data |
人员 | 一个简单的数据 bean 接口,描述一个Person 的属性。 |
员工 | Person 接口的扩展,添加了Salary 属性。 |
|
用户 | Employee 接口的扩展,添加了Pass 属性。 |
|
dev.easyref.util |
参数 | 一个用于执行所有反射工作的实用程序类。 |
DataBean | 一个描述 Data-Bean 需要的基本方法的接口。 | |
DataBeanProxy | Arguments 类的一个扩展,自动提供代码来支持 Data-Bean 属性。 |
它是如何工作的
让我们检查一下DemoApplication
的 main 方法
01 public static void main(String[] args) {
02 ArrayList list = new ArrayList();
03 // Create 3 users..
04 addUser(list, "WOOGA", 1500.0f, 25, "Ruth", "Barak");
05 addUser(list, "TESTER", 2000.0f, 40, "Odded", "Barak");
06 addUser(list, "BOOGA", 3000.0f, 35, "Doron", "Barak");
07 // Sort the list by the FirstName..
08 Collections.sort(list, new Comparator() {
09 public int compare(Object o1, Object o2) {
10 String s1 = ((User)o1).getFirstName();
11 String s2 = ((User)o2).getFirstName();
12 return s1.compareTo(s2);
13 }
14 });
15 // Print out the list..
16 System.out.println(list);
17 }
我们可以看到有趣的部分在第 4 到 6 行之间,在这里创建了三个 User
实例。 看看 addUser(...)
方法可以更清楚地了解情况
01 public static void addUser(Collection list, String psswd,
float salary, int age, String firstName, String lastName) {
02 // Create a User DataBeanProxy object..
03 User user = (User)DataBeanProxy.newDataBean(User.class);
04 // Set the properties..
05 user.setAge(age);
06 user.setSalary(salary);
07 user.setPassword(psswd);
08 user.setLastName(lastName);
09 user.setFirstName(firstName);
10 // Add the User instance to the list..
11 list.add(user);
12 }
这里重要的是第 3 行,其中 DataBeanProxy
类用作工厂来创建 User
实例。 新创建的实例确实实现了 User
接口,但要了解它是如何实现的以及数据属性保存在哪里,您必须查看 DataBeanProxy
类的内部。
结论
希望本文有助于认识到反射的力量,以及反射 - 虽然可以说打破了 OOP 方法 - 如何可以作为 API 构建工具。