Reputation: 127
I have the following code:
ArrayList<Object> list = new ArrayList<Object>();
list.add("StringType");
list.add(5);
list.add(new RandomClass());
List<Class<?>> classes = new ArrayList<>();
classes.add(String.class);
classes.add(int.class);
classes.add(RandomClass.class);
for (int i = 0; i < list.size(); i++) {
if (classes.get(i).isInstance(list.get(i))) {
...
}
}
if (isvalid)
mymethod(...);
public void mymethod(String string, int num, RandomClass randomClass){ }
Now I'm trying to cast the object into the right type with a method using a string argument.
Instead of:
mymethod( (String) list.get(0), (int) list.get(1), (RandomClass) list.get(2) );
I would like to reuse the definition created above for the cast.
mymethod( ( define.get(0) ) list.get(0), .... );
I've also tried using the Class.cast(obj) but of course it returns a type '?' which again defeats the purpose of casting it again using (String).
Upvotes: 0
Views: 59
Reputation: 34628
In order to be able to select the appropriate method, the compiler needs to know at compile time what the types of the arguments are. Or at least a general category such as List<?>
etc.
This is needed to support overloading of methods. There can be many methods with the same name, but with different parameter types.
Since you are asking the VM to call a method when it can't determine which exact method you want to call, because it doesn't know at compile time what the types of your parameters are, what you ask cannot be done in Java.
Here is the relevant section from the Java Language Specification.
What it says is that the system selects at compile time which method signature to use, and then, at run time, the particular implementation of that method signature that's correct for the given instance.
Upvotes: 1
Reputation: 61158
What is type safety?
In computer science, type safety is the extent to which a programming language discourages or prevents type errors.
If code is type safe, then the compiler can verify, at compile time, that all the types are correct:
String getName() {
return "name";
}
The compiler knows that "name" must be a String
so it can verify that this code will never throw a type error.
Once you do something like:
int getNumber() {
(int) number;
}
The need to explicitly cast to int
tells you that this code has an error condition, namely when number
is not of type int
or a type that is assignable to int
.
How does it affect you?
Your code:
define.get(0).cast(list.get(0))
You want the return type of this statement to be of the type of get(0)
. But the compiler has no way of knowing, at compile time, what define.get(0)
returns. This is inidcated to you by the return type.
You have a List<Class<?>>
, i.e. a List
of a class of "I don't care what type". You then use a member of this List
to cast a member of your other List
- the only result can be an "I don't care what type".
You can hack around this with:
<T> T get(final int i) {
return (T) define.get(i).cast(list.get(i));
}
This will happily compile:
final String thing = get(0);
As will:
final int thing = get(0);
i.e. all that you have done is to endogenise the cast. The error condition still exists.
Upvotes: 2
Reputation: 3353
You don't actually need to store object's class separately
list.get(0).getClass()
will get you the class of the stored object and then you can use what @Eran suggested
and
list.get(0).getClass().getName()
will get you the String name of your class
Upvotes: 0
Reputation: 393846
define.get(0).cast(list.get(0))
would attempt to cast list.get(0)
to the required type.
Upvotes: 2