Welcome to the Java Developer Connection Java Technology Fundamentals Newsletter.
This monthly newsletter provides a way for you to learn the basics of the Java programming language, discover new resources, and keep up-to-date on the latest additions to the JDC's New to Java Programming Center.
Java Programming Language Basics
Reflection Basics and Class Class
The standard J2SE platform libraries include a reflection API. This API allows classes to reflect on themselves, to see their inner selves. Typically not used by developers, but by tool developers such as those creating an IDE like NetBeans, the reflection API lets you discover the names of classes, methods, and fields. Just finding out the names isn't all you can do though. You can also invoke those methods and access arrays without using square brackets.
The heart of the reflection API is the Class class. This class allows you to find out the name of a class, its access modifiers, fields, methods, etc. For any instance of a class, you can get its Class class by calling the getClass method:
Class c = anInstance.getClass();
If you don't happen to have an instance of a class (and don't want to create one), just attach .class to the end of the class name and you have the Class instance for that class.
Class c = MyClass.class;
The same even works for primitives:
Class c = int.class;
This last one might seem odd, but it allows you to specify argument types when calling methods (via Reflection) that accept primitive arguments.
One thing typically done is creating a Class by passing its string name to the forName method of Class.
Class c = Class.forName("java.awt.Button");
This is very common in JDBC technology. This is done so is that so that at compile time you don't have to have the class within the quoted string available. So, if you change JDBC drivers, you won't have to recompile your program if the driver's class name was the quoted string.
Note: When naming the variable for the Class instance, don't name it class. As this is a reserved word, the compiler will think you are trying to define a new class in an inappropriate spot.
Once you have a Class class, that's where the fun begins. You can find out the name of the class with its getName method.
Class c = javax.swing.JButton.class
System.out.println("Name: " + c.getName());
Or, you can find out its superclass with getSuperclass:
System.out.println("Super: " + c.getSuperclass().getName());
[Yields javax.swing.AbstractButton in the case of the JButton.]
Moving from classes to methods takes us to the Method class, found in the java.lang.reflect package. With the Method class, you can discover all methods of a class (with getMethods) and even invoke them (with invoke).
The following program demonstrates getting the methods of a class, where the class name comes from the command line.
import java.lang.reflect.*;
public class ListMethods {
public static void main(String args[]) {
if (args.length == 0) {
System.err.println(
"Please include fully qualified class name on command line");
return;
}
for (int i=0, n=args.length; i<n; i++) {
listMethods(args[i]);
}
}
private static void listMethods(String name) {
try {
Class c = Class.forName(name);
System.out.println("----" + c.getName() + "----");
Method methods[] = c.getMethods();
for (int i=0, n=methods.length; i<n; i++) {
System.out.println(methods[i].getName());
System.out.println("\t" + methods[i]);
}
} catch (ClassNotFoundException e) {
System.out.println("Bad classname: " + name);
}
}
}
For each name passed on the command line, you'll discover the methods available to a class. Run on itself, you get the following output:
----ListMethods----
main
public static void ListMethods.main(java.lang.String[])
hashCode
public native int java.lang.Object.hashCode()
getClass
public final native java.lang.Class java.lang.Object.getClass()
wait
public final void java.lang.Object.wait(long,int)
throws java.lang.InterruptedException
wait
public final void java.lang.Object.wait()
throws java.lang.InterruptedException
wait
public final native void java.lang.Object.wait(long)
throws java.lang.InterruptedException
equals
public boolean java.lang.Object.equals(java.lang.Object)
notify
public final native void java.lang.Object.notify()
notifyAll
public final native void java.lang.Object.notifyAll()
toString
public java.lang.String java.lang.Object.toString()
Notice that the output includes all the methods available through its superclass, too. To limit the output to only those methods declared in the class itself, change the getMethods call to getDeclaredMethods and you'll get the following output instead:
----ListMethods----
main
public static void ListMethods.main(java.lang.String[])
listMethods
private static void ListMethods.listMethods(java.lang.String)
While the getMethods method of Class allows you to get all the methods of a class, more typically, you want a specific method of a class. For that, there is the getMethod(String name, Class types[]) method. By passing in the name of the method you want, and an array of the Class types for the arguments, you can get a specific method. Once you have that Method, you can invoke it with the invoke(Object instance, Object args[]) method. For static methods, the instance argument can be null.
The tricky part of invoking of methods through reflection is the Class[] and Object[] arguments. To find a method, you have to provide an array of the Class types for the arguments. That means if you wanted to locate the following method of String:
regionMatches(boolean ignoreCase,
int toffset,
String other,
int ooffset,
int len)
The Class[] declaration would look something like the following:
Class types[] = {boolean.class,
int.class,
String.class,
int.class,
int.class};
The values for the arguments don't matter when finding a method, only the class types. At invoke time, you pass in the actual argument values. For primitive types, you must box them up as objects (like using Integer for int).
The following demonstrates invoking a method through reflection, and inserting a String in the middle of a StringBuffer:
public StringBuffer insert(int offset, String str)
While regionMatches would work, this example will be a little less complex.
import java.lang.reflect.*;
public class Combine {
public static void main(String args[]) {
try {
StringBuffer buffer = new StringBuffer("Held");
Class c = buffer.getClass();
Class types[] = {int.class, String.class};
Method method = c.getMethod("insert", types);
Object theArgs[] = {new Integer(2), "llo, Wor"};
System.out.println("Before: " + buffer);
method.invoke(buffer, theArgs);
System.out.println("After: " + buffer);
} catch (Exception e) {
System.err.println("Unable to invoke method: " + e);
}
}
}
For more information on the Reflection API, see the trail in the Java Tutorial.
Java Bits
The Java Platform for Developers and End Users
Java technology runs across all types and sizes of devices, from computer chips to cell phones to some of the world's largest computers. By enabling all types of programs to run on just about any machine, regardless of operating system, Java technology makes it possible to create applications from multiplayer role-playing fantasy games to detailed market tracking applications.
Because of the diversity in application possibilities through using Java technologies, standards for the platform are essential. Sun adheres to standards for the Java platform, ensuring application compatibility and interopability.
Dependencies can occur if you create applications using a JVM provided with an operating system. If the JVM
your application depends on is no longer shipped with the operating system, or it doesn't meet standards, your end-users may suffer error messages and frustrating troubleshooting.
Avoid proprietary system dependencies simply by developing with the official Sun Java platform that adheres to industry standards, ensuring your applications run in the future.
For online applications you develop, consider including the Get Java logo on appropriate web sites so end-users have latest version of Java running on their systems, and not some outdated JVM, or none at all.
When you download the J2SE or J2EE development kits, you have the APIs and tools you need to write enterprise-worthy applets, applications, and servlets. To add specialized functionality, such as JavaMail,
or Java Advanced Imaging, you need to download additional APIs and tools, optional packages.
To ensure your applications run smoothly on a variety of platforms, download the official Sun Java development environment and packages:
For web sites to ensure end-user's systems have the official Sun software.
Making Sense of the Java Class
Class Object
Every class, including those from the Java API and any you create, has class Object as a superclass because Object is the root of the class hierarchy.
Although every class extends class Object, you don't need to write:
Object obj = new Dog("Bandit", "Mixed Breed");
Instead, class Dog automatically extends Object, and inherits all of Object's methods. If a class returns a type Object, then you'll need to cast it to the appropriate object:
Dog dg = (Dog)obj;
Class Object defines the basic state and behavior that all objects must have, such as the ability to compare an object to another object, to convert to a string, to wait on a condition variable, to notify other objects that a condition variable has changed, and to return the class of the object. In other words, the real meat of this class is in the methods all your classes and Java classes inherit. In fact, all objects, including arrays, implement the methods of this class.
When you create a class, you automatically have the Object class methods available to your object. Here are a few:
public boolean equals(Object obj) -- Indicates whether some other object is "equal to" this one.
public String toString() -- Returns a string representation of the object. In general, the toString method returns a string that "textually represents" this object. The result should be a concise but informative representation that is easy for a person to read.
public final void notify() -- Wakes up a single thread that is waiting on this object's monitor. If any threads are waiting on this object, one of them is chosen to be awakened. The choice is arbitrary and occurs at the discretion of the implementation. A thread waits on an object's monitor by calling one of the wait methods.
public final void wait(long timeout) throws InterruptedException -- Causes current thread to wait until either another thread invokes the notify() method or the notifyAll() method for this object, or a specified amount of time has elapsed.
protected void finalize() throws Throwable -- Called by the garbage collector on an object when garbage collection determines that there are no more references to the object. A subclass overrides the finalize method to dispose of system resources or to perform other cleanup.
protected Object clone() throws CloneNotSupportedException -- Creates and returns a copy of this object.
There are more useful methods available to any class you create or use because all classes inherit from the Object class. Take some time to read through the documentation about this class so you know what is readily and automatically available to your classes.
Program Challenge
Application Lookup
Create a program that offers a text field to the user for input. In that text field, the user enters in the name of a color that has a constant in the Color class, like RED, GREEN, or BLUE.
Based on the text in the input field, use the Field class to use reflection to find its current value. Then, change the background color of the program to that color.
See a possible solution to the Challenge.
Java Workbook
Drawing
Create a simple drawing program that draws as you drag your mouse over the screen. Make clicking the mouse clear the screen.
Quiz
Reflection
Test what you learned about reflection in this online quiz.
Java Programming Language for Visual Basic Programmers
Java Technology Training for Visual Basic Developers: Learn how to program "write once and run anywhere" applications
For More Information
Downloading the Java 2 Platform
For most Java development, you need the class libraries, compiler, tools, and runtime environment provided with the J2SE development kit.
Subscribe to the following newsletters for the latest information about technologies and products in other
Java platforms:
- Core Java Technologies Newsletter. Learn about new products, tools, resources, and events of interest to
developers working with core Java technologies.
- Wireless Developer Newsletter. Learn about the latest releases, tools, and resources for developers
working on wireless and Java Card technologies and applications.
- Core Java Technologies Tech Tips (formerly JDC Tech Tips) Get expert tips, sample code solutions, and
techniques for developing in the Java 2 Platform, Standard Edition (J2SE)
You can subscribe to these and other JDC publications on the JDC Newsletters and Publications
page
IMPORTANT: Please read our Terms of Use, Privacy, and Licensing policies:
http://www.sun.com/share/text/termsofuse.html
http://www.sun.com/privacy/
http://developer.java.sun.com/berkeley_license.html
Comments? Send your feedback on the Java Technology Fundamentals Newsletter to: dana.nourie@sun.com
Go to the subscriptions
page to subscribe or unsubscribe to this newsletter.
ARCHIVES: You'll find the Java Technology Fundamentals Newsletter archives at:
http://developer.java.sun.com/developer/onlineTraining/new2java/supplements/
Copyright 2003 Sun Microsystems,
Inc. All rights reserved. 4150 Network Circle, Santa Clara, CA 95054
Trademark Information: http://www.sun.com/suntrademarks/
Java, J2EE, J2SE, J2ME, and all Java-based marks are trademarks or registered trademarks of Sun
Microsystems, Inc. in the United States and other countries.
|