65.9K
CodeProject 正在变化。 阅读更多。
Home

Java 泛型代码 - 反射的力量

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.35/5 (7投票s)

2004年9月30日

CPOL

3分钟阅读

viewsIcon

52937

downloadIcon

1210

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接口的扩展,添加了Password属性。
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 构建工具。

© . All rights reserved.