Google
 
Web unafbapune.blogspot.com

Saturday, July 12, 2008

 

Java Enum Puzzler

What does the following print ?
public enum FooEnum {
FOO { @Override public void bar() {} };
public abstract void bar();

public static void main(String...args) {
System.out.println(FOO.getClass().isEnum());
}
}
Answer:

FOO is an enum value in FooEnum. The class of FOO must therefore be an enum, and it should print "true". Right ? If you give it a try, surprisingly it will print "false". Why ?

Peeking into the JDK source code of Class.java,
public boolean isEnum() {
// An enum must both directly extend java.lang.Enum and have
// the ENUM bit set; classes for specialized enum constants
// don't do the former.
return (this.getModifiers() & ENUM) != 0 &&
this.getSuperclass() == java.lang.Enum.class;
}
Now if you tried to print out the super class of FOO.class, it would print FooEnum.class, rather than Enum.class. The comparison of the super class of FOO.class against Enum.class would therefore fail in the second condition of the return statement.

To me, this looks like a bug either in the javac compiler, or in the implementation of Class.isEnum().

Why is it probably a bug in the javac compiler ? Well, shouldn't the super class of FOO.class be Enum.class, instead of FooEnum.class ? (Special thanks to Dhanji R. Prasanna for pointing this out.)

Why is it probably a bug in Class.isEnum() ? Well, shouldn't it recursively check all the super classes of FOO.class for Enum.class, instead of just the direct super class ? And why does it need to compare the super class with Enum.class at all, when there is already the checking for the ENUM class modifier ?

What do you think ?

Update on 7/13/2008: Please vote for bug 6710708.

Friday, July 11, 2008

 

Dumping a JavaBean as name/value pairs ?

Sometimes it's useful to deeply dump out the properties of a complex JavaBean as name/value pairs, perhaps for debugging purposes, even when none of the toString methods of the classes involved are defined. This is especially the case when the JavaBean classes are written by a third party.

Now how would you go about doing that ?

How about using the Jarkarta commons-lang's ToStringBuilder.reflectionToString method ? It doesn't cut it, as it relies on the toString method of the individual classes involved.

How about XMLEncoder or XStream ? They work pretty nicely. However, by default XStream generates not just the public properties but all other fields as well. In both cases, the generated XML would need to be further transformed into name/value pairs.

Another way I can think of is to take advantage of the latest BeanSourceHandler SPI as a side effect of performing a deep clone via the open-source library Beanlib (beanlib-3.3.0beta18). What do I mean ? Here is an example:
Object bean = ...
// Dump out the entire JavaBean
// when none of the toString methods are defined.
BeanReplicator.newBeanReplicatable(customTransformer()).replicateBean(bean);

private static BeanTransformerSpi customTransformer() {
BeanTransformerSpi beanTransformer = BeanTransformer.newBeanTransformer();
return beanTransformer.initBeanSourceHandler(new BeanSourceHandler() {
public void handleBeanSource(Object fromBean, Method readerMethod, Object propertyValue) {
System.out.println(
String.valueOf(fromBean.getClass().getSimpleName() + "."
+ readerMethod.getName() + "=" + propertyValue));
}
});
}

Wednesday, July 02, 2008

 

Little Java Quiz - File loaded from classpath

Given:
  1. a file with a given name;
  2. the file is located in the file system;
  3. the file can be loaded via the classpath;
How can the code figure out the physical location (ie absolute path) of the file ?

(Don't peek if you want to give it a try!)

Answer:
    String filePath = Thread.currentThread()
.getContextClassLoader()
.getResource(filename)
.getFile();

This page is powered by Blogger. Isn't yours?