Inventory
Scenario:
We are designing software for a car dealer. We design an Inventory class
that uses a LinkedList to keep track of all cars on the lot. Each car is represented
by an object instance of particular class designed for that car. However, when
we design the software we do not know what car will arrive in the future, thus
we cannot use conditional statements to create an object for a particular class.
Instead, we decide to use the Reflection API to create an object.
Solution:
The addCar
method takes in two parameters:
String carName -
represents the name of the car and the name of class that is designed for that
particular car; Object[]
initArgs- initial arguments to be passed to the constructor of the car
class. The initArgs
objects are in the same order as the parameters in the constructor.
Below is a fragment of code from method addCar.
Class carClass = Class.forName(carName);
Class[] initClassArgs= new Class[initArgs.length];
for(int i=0;i<initArgs.length;i++){
initClassArgs[i]=initArgs[i].getClass();
}
Constructor carConstructor =
carClass.getConstructor(initClassArgs);
Car newCar = (Car)carConstructor.newInstance(initArgs);
inventory.add(newCar);
First, we obtain a Class object for the car we want to create. This Class object allows us to access metadata for that particular car class. Using the forName method we get Class object for the class with the name same as carName. We then want to find a constructor for the particular carName class. To obtain the constructor, we need to match the initArgs to parameters of the constructor. We thus create an array of Class that has Class objects for each object of initArgs. Using the getConstructor method, we try to match the constructor to the arguments in intiArgs. (We could pass in null to obtain the constructor without any parameters.) Once we have the constructor, we can create a new instance of that class by the newInstance(Object[]) method where we pass the arguments we received in the initArgs.
Conclusion:
When we write the code, we do not know what cars are available. Using Reflection
we can create instance of classes (to represent the cars) that might be written
after the code for addCar
is written. Dynamically loading classes using Reflection allows for better
code because we need not alter the code every time a new class is introduced.
This allows our program to be more versatile in that as changes are made in the
future, the code does not need to be updated, it adapts to certain changes as
result of use of Reflection.
Source Code (Inventory.java) Source Code (Accord.java) Source Code (Car.java)