Reputation: 3668
I'm writing some code that works with the JMX api. Specifically I am making use of the getAttribute
method of MBeanServerConnection
The javadocs for the getAttribute
method says that it returns Object
, but what I have found is that depending on the MBean, sometimes it can return an Object
, and other times it can return an Object[]
array.
Because I want to deal with the return from getAttribute
consistently, I have written the following code:
Object attr = mBeanServer.getAttribute(objName, attributeName);
Object[] attributes = new Object[]{};
if (attr.getClass().isArray()) {
attributes = (Object[])attr; // create my array by casting the return from getAttribute
} else {
attributes = new Object[] {attr}; // create my array with just one element
}
for (int i=0; i < attributes.length; i++) {
// deal with each attribute ...
}
Hopefully you can see the idea. It's probably a naive solution, but basically I want to deal with the return from getAttribute
consistently, regardless of whether its a single Object
or an Object[]
array.
The above works ... for the most part! ... but I've now found a case where 'getAttribute' has returned an array of long
(the primitive, rather than class). Because of this, my cast throws a java.lang.ClassCastException: [J cannot be cast to [Ljava.lang.Object;
I understand the exception - it cannot cast an array of long
to an array of Object
- but I don't know how to solve it.
Personally, I think the method signature of getAttribute
sucks! Returning 'Object' to cover pretty much anything - an object, an array of objects, or an array of primitives - feels like a cop out to me. But its not my api, and I've got to work with it.
Appreciate any thoughts or ideas on how I can solve this?
Cheers
Nathan
Upvotes: 1
Views: 536
Reputation: 5415
How about this?
import java.lang.reflect.*;
import java.util.*;
public class ArrayTest
{
public static void main(String[] args)
{
evaluate("Hello");
evaluate(new Boolean[]{Boolean.TRUE, Boolean.FALSE});
evaluate(new int[]{0, 1, 2});
evaluate(null);
}
public static void evaluate(Object object)
{
List<String> primitiveArrayTypes = Arrays.asList(new String[] {
"boolean[]", "byte[]", "char[]", "double[]",
"float[]", "int[]", "long[]", "short[]"
});
if (object == null)
{
System.out.println("Null object.");
return;
}
Class objClass = object.getClass();
if (objClass.isArray())
{
if (primitiveArrayTypes.contains(objClass.getCanonicalName()))
{
System.out.println("Contents of primitive array:");
for (int i = 0; i < Array.getLength(object); i++)
{
System.out.println(Array.get(object, i));
}
}
else
{
System.out.println("Contents of Object array:");
for (Object obj : (Object[]) object) // cast should now always work
{
System.out.println(obj);
}
}
}
else
{
System.out.println("Not an array: " + object);
}
System.out.println("---");
}
}
Upvotes: 1
Reputation: 691765
if (o instanceof int[]) {
...
}
else if (o instanceof boolean[]) {
...
}
...
Maybe there's some more elegant solution, but you don't tell what you want to do with the attribute.
Upvotes: 1