Click here to Skip to main content
15,881,248 members
Articles / Programming Languages / Java / Java SE
Article

Java Generic Code - Power Of Reflection

Rate me:
Please Sign up or sign in to vote.
3.35/5 (7 votes)
30 Sep 2004CPOL3 min read 52.4K   1.2K   18  
Java's Reflection enables programs to automatically flesh out simple interfaces to create automated data objects

Introduction

Whenever there is an application to write, breaking it up to small pieces is a great idea. The smallest piece of any application would probably be a data object, or a simple Bean in Java. Java Beans are simple Java classes that have a distinctive look and behavior. Their simplest purpose is to contain data and they accomplish this by having properties. Each property is actually a data-member containing/referencing the actual data and a couple of methods, a getter method and a setter method. Thus, the simplest data-bean describing a person could be expressed as such:

Java
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);
}

Your first response could probably be, "where are the data-members?", or "why did you use an interface and not a class?" and you would be perfectly right in asking either one of those two important questions. The whole idea of breaking things down to small pieces is to create an API that need not be changed after it is agreed upon by all parties involved in the design and development of the code. Only then, should we generate code to support and use such APIs. However, during that first stage when APIs are developed, sometimes you need to add a property, change a property or maybe introduce a whole new Bean into the system. Testing your APIs is impossible if your Beans don't actually support their properties, so you have to actually implement some sort of a basic bean, or the Data-Bean as I call it.

In this article, I will make use of Java's Reflection to handle the automation of Data-Beans without writing more code than the previously mentioned interface or more like it.

Background

The code in this article uses the Arguments class I have described in an earlier article titled: "Java Generic Code - Reflection, the Easy Way", and although the Arguments class is included in the supplied source, I would advise you to read my article about Reflection just so that my DataBeanProxy class will be easier to understand.

How the Code is Organized

Simply run the dev.easyref.tester.DemoApplication class or double click on the JAR file supplied. The class structure is as follows:

PackageSource FilePurpose
dev.easyref.testerDemoApplicationThe demo's main class.
dev.easyref.dataPersonA simple data bean interface describing a Person's properties.
EmployeeAn extension to the Person interface adding the Salary property.
UserAn extension to the Employee interface adding the Pass<code>word property.
dev.easyref.utilArgumentsA utility class used to perform all the Reflection work.
DataBeanAn interface describing basic methods a Data-Bean will need.
DataBeanProxyAn extension of the Arguments class that automatically provides code to support Data-Bean properties.

How Things Work

Let's examine the main method of DemoApplication:

Java
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  }

We can see that the interesting part is between lines 4 to 6, where three User instances are created. Looking at the addUser(...) method clears up things a little:

C#
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  }

The important bit here is line 3 where the DataBeanProxy class is used as a Factory to create a User instance. The newly created instance does implement the User interface but to find out how, and where the data-properties are kept, you'll have to peek under the hood of the DataBeanProxy class.

In Conclusion

Hopefully this article helps in realizing the power of Reflection and also how Reflection -- although arguably breaks OOP methodologies -- can be useful as an API building tool.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
Canada Canada
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
-- There are no messages in this forum --