java: How can I do dynamic casting of a variable from one type to another?
Regarding your update, the only way to solve this in Java is to write code that covers all cases with lots of
if
andelse
andinstanceof
expressions. What you attempt to do looks as if are used to program with dynamic languages. In static languages, what you attempt to do is almost impossible and one would probably choose a totally different approach for what you attempt to do. Static languages are just not as flexible as dynamic ones :)Good examples of Java best practice are the answer by BalusC (ie
ObjectConverter
) and the answer by Andreas_D (ieAdapter
) below.
That does not make sense, in
String a = (theType) 5;
the type of a
is statically bound to be String
so it does not make any sense to have a dynamic cast to this static type.
PS: The first line of your example could be written as Class<String> stringClass = String.class;
but still, you cannot use stringClass
to cast variables.
Very simple Java Dynamic Casting
You want to instantiate a class by it's name?
First of all, you need to make a Class<?>
object:
Class<?> cls = Class.forName(strClassName);
Then instantiate this (note, this can throw various exceptions - access violation, ClassNotFound
, no public constructor without arguments etc.)
Object instance = cls.newInstance();
Then you can cast it:
return (SomeClass) instance;
Please make sure you understand the differences between:
- A class name (approximately a file name)
- A class object (essentially a type information)
- A class instance (an actual object of this type)
You can also cast the cls
object to have type Class<? extends SomeClass>
, if you want. It doesn't give you much, though. And you can inline it, to:
return (SomeClass)(Class.forName(strClassName).newInstance());
Oh, but you can do type checking with the cls
object, before instantiating it. So you only instanciate it, if it satisfies your API (implements the interface you want to get).
EDIT: add further example code, towards reflection.
For example:
if (cls.isInstance(request)) {
// ...
}
For invoking methods, you either need to know an interface that you can cast to, or use reflection (the getMethod
methods of the cls
object):
Method getRequest = cls.getMethod("getRequest");
getRequest.invoke(request);
Dynamic casting of object to a type
Finally I've found a workaround :
private Object changeValueToSuitDestType(Object value, Class<?> destType) {
if (destType == null || value == null) {
return value;
}
String typeString = destType.toString();
String valueString = value.toString();
boolean isNull = TextUtils.isEmpty(valueString)
|| valueString.equalsIgnoreCase("null");
if (typeString.equalsIgnoreCase("boolean")
|| destType == Boolean.class) {
if (isNull) {
if (destType == Boolean.class) {
return null;
} else {
return false;
}
} else {
return Boolean.parseBoolean(value.toString());
}
} else if (typeString.equalsIgnoreCase("byte")
|| destType == Byte.class) {
if (isNull) {
if (destType == Byte.class) {
return null;
} else {
return 0;
}
} else {
return Byte.parseByte(value.toString());
}
} else if (typeString.equalsIgnoreCase("short")
|| destType == Short.class) {
if (isNull) {
if (destType == Short.class) {
return null;
} else {
return 0;
}
} else {
return Short.parseShort(value.toString());
}
} else if (typeString.equalsIgnoreCase("int")
|| destType == Integer.class) {
if (isNull) {
if (destType == Integer.class) {
return null;
} else {
return 0;
}
} else {
return Integer.parseInt(value.toString());
}
} else if (typeString.equalsIgnoreCase("long")
|| destType == Long.class) {
if (isNull) {
if (destType == Long.class) {
return null;
} else {
return 0L;
}
} else {
return Long.parseLong(value.toString());
}
} else if (typeString.equalsIgnoreCase("float")
|| destType == Float.class) {
if (isNull) {
if (destType == Float.class) {
return null;
} else {
return 0F;
}
} else {
return Float.parseFloat(value.toString());
}
} else if (typeString.equalsIgnoreCase("double")
|| destType == Double.class) {
if (isNull) {
if (destType == Double.class) {
return null;
} else {
return 0D;
}
} else {
return Double.parseDouble(value.toString());
}
} else if (typeString.equalsIgnoreCase("char")
|| destType == Character.class) {
if (isNull) {
if (destType == Character.class) {
return null;
} else {
return '\u0000';
}
} else {
return value.toString().charAt(0);
}
} else if (destType == String.class) {
if (isNull) {
return null;
} else {
return value.toString();
}
}
return value;
}
Thanks to all for your valuable answer and for me I find like there is no other easy way for this. If you guys find something like this, please let me know. Once again thanks to all.
Related Topics
Setting Jpg Compression Level with Imageio in Java
How to Count Frequency of Characters in a String
How to Define a Relative Path in Java
How to Create a Multidimensional Arraylist in Java
Executing Another Application from Java
Io Error: the Network Adapter Could Not Establish the Connection
How to Read File from End to Start (In Reverse Order) in Java
Why Do I Get the "Unhandled Exception Type Ioexception"
Rationale for Matcher Throwing Illegalstateexception When No 'Matching' Method Is Called
How to Split a Java String at Backslash
Simple Division in Java - Is This a Bug or a Feature
How to Concatenate Int Values in Java
What's the Purpose of Try-With-Resources Statements
Calling Method from Constructor