Casting - foreach - java
I have a one method like this:
private void myMethod(List<?> myLists) {
for (Object val : myLists) {
val.getMyOtherMethod(); // for example
}
}
How can I casting val
to one of m开发者_如何学编程y objects?
All my objects (list objects) contain same methods, like as getMyOtherMethod()
BR
edit: ---------------------------------------------------------------------
I called myMethod few times, like as:
List<MyClas.MySubclass1> var1;
List<MyClas.MySubclass2> var1;
List<MyClas.MySubclass3> var1;
...
...
myMethod(var1);
myMethod(var2);
myMethod(var3);
In this case, I do not know, witch subclass I send MySubclass1, MySubclass2 or MySubclass3. That is important for foreach loop.
You need a List of elements which implement getMyOtherMethod()
interface ImplementsGetMyOtherMethod {
void getMyOtherMethod();
}
private void myMethod(List<? extends ImplementsGetMyOtherMethod> myLists) {
You can only cast to a type which your objects actually have. Having the right method is not sufficient here. If you have different classes which all have the same method, let them implement an interface which provides the method, too.
Then you can do
for (Object val : myLists) {
((MyInterface) val).getMyOtherMethod();
}
or (if you have multiple methods):
for (Object val : myLists) {
MyInterface mi = (MyInterface) val;
mi.getMyOtherMethod();
mi.doSomething();
}
Of course, then you would normally use List<MyInterface>
instead of List<?>
, and avoid the casting altogether.
The right way to solve this problem is to use generics to enforce compile-time type checking. If all the objects implement a common interface
interface IFoo {
Bar getMyOtherMethod();
}
then myMethod
should take a List<IFoo>
and not a List<?>
:
private void myMethod(List<IFoo> myLists)
{
for (IFoo val : myLists)
{
val.getMyOtherMethod();
}
}
If you find yourself having to cast outside of equals()
, there's almost certainly a better, idiomatic way to accomplish the task.
Define/use an interface they all implement:
interface HasMyOtherMethod {
void getMyOtherMethod();
}
private <T extends HasMyOtherMethod> void myMethod(List<T> myLists) {
for (T val : myLists) {
val.getMyOtherMethod();
}
}
EDITED: Added generic upper bound: Any subclass of HasMyOtherMethod will work.
The advantage of this over casting is that this is checked at compile time, whereas the cast is checked at run time.
You always want compile time checking if you can get it, otherwise you risk compiling, deploying to production, then one day exploding at runtime in production.
If you can, avoid casting all together:
private void myMethod(List<YourType> myLists) {
for (YourType val : myLists) {
val.getMyOtherMethod(); // for example
}
}
you can avoid casting all together with generic wildcards
private void myMethod(List<? extends YourInterface> myLists) {
for (YourInterface val : myLists) {
val.getMyOtherMethod(); // for example
}
}
this has the advantage of other types being available that implement from YourInterface
with that method
精彩评论