【问题标题】:Casting - foreach - java铸造 - foreach - java
【发布时间】:2011-09-17 05:03:28
【问题描述】:

我有一个这样的方法:

private void myMethod(List<?> myLists) {

   for (Object val : myLists) {
       val.getMyOtherMethod(); // for example
   }

}

如何将val 投射到我的对象之一?

我的所有对象(列表对象)都包含相同的方法,例如 getMyOtherMethod()

BR

编辑: -------------------------------------------------- -------------------

我调用了 myMethod 几次,例如:

List<MyClas.MySubclass1> var1;
List<MyClas.MySubclass2> var1;
List<MyClas.MySubclass3> var1;
...
...

myMethod(var1);
myMethod(var2);
myMethod(var3);

在这种情况下,我不知道,我发送 MySubclass1、MySubclass2 或 MySubclass3 的女巫子类。这对于 foreach 循环很重要。

【问题讨论】:

    标签: java list casting for-loop foreach


    【解决方案1】:

    您需要一个实现 getMyOtherMethod() 的元素列表

    interface ImplementsGetMyOtherMethod {
       void getMyOtherMethod();
    }
    
    private void myMethod(List<? extends ImplementsGetMyOtherMethod> myLists) {
    

    【讨论】:

      【解决方案2】:

      您只能转换为您的对象实际具有的类型。在这里,拥有正确的方法是不够的。如果你有不同的类,它们都有相同的方法,让它们也实现一个提供方法的接口。

      那你就可以了

      for (Object val : myLists) {
         ((MyInterface) val).getMyOtherMethod();
      }
      

      或者(如果你有多种方法):

      for (Object val : myLists) {
         MyInterface mi = (MyInterface) val;
         mi.getMyOtherMethod();
         mi.doSomething();
      }
      

      当然,那么您通常会使用List&lt;MyInterface&gt; 而不是List&lt;?&gt;,并且完全避免强制转换。

      【讨论】:

        【解决方案3】:

        解决这个问题的正确方法是使用泛型来强制编译时类型检查。如果所有对象都实现一个通用接口

        interface IFoo {
            Bar getMyOtherMethod();
        }
        

        那么myMethod 应该使用List&lt;IFoo&gt; 而不是List&lt;?&gt;

        private void myMethod(List<IFoo> myLists)
        {
           for (IFoo val : myLists)
           {
               val.getMyOtherMethod();
           }
        }
        

        如果您发现自己不得不在 equals() 之外进行投射,几乎可以肯定有一种更好的惯用方式来完成任务。

        【讨论】:

        • 可以像 myMethod(listObjectOfClassThatImplementsIfoo) 一样调用 myMethod
        【解决方案4】:

        定义/使用他们都实现的接口:

        interface HasMyOtherMethod {
            void getMyOtherMethod();
        }
        
        private <T extends HasMyOtherMethod> void myMethod(List<T> myLists) {
           for (T val : myLists) {
               val.getMyOtherMethod();
           }
        }
        

        已编辑:添加了通用上限: HasMyOtherMethod 的任何子类都可以工作。

        这种过度强制转换的优点是它在编译时检查,而强制转换在运行时检查。

        您总是希望在编译时检查是否可以得到它,否则您将面临编译、部署到生产环境的风险,然后有一天在生产环境中的运行时爆炸。

        【讨论】:

        • 如果你有 HasMyOtherMethod 的任何子类型的列表,这可行但不方便。
        【解决方案5】:

        如果可以,请避免一起投射:

        private void myMethod(List<YourType> myLists) {
        
           for (YourType val : myLists) {
               val.getMyOtherMethod(); // for example
           }
        
        }
        

        【讨论】:

        • 我调用了 myMethod 几次,例如: List var1;列表 var1;列表 var1; ... ... myMethod(var1);我的方法(var2);我的方法(var3);在这种情况下,我不知道,女巫子类我发送 MySubclass1、MySubclass2 或 MySubclass3。这对于 foreach 循环很重要。
        • Peter 的解决方案更好,但总体思路相同。
        【解决方案6】:

        您可以避免与通用通配符一起进行强制转换

        private void myMethod(List<? extends YourInterface> myLists) {
        
           for (YourInterface val : myLists) {
               val.getMyOtherMethod(); // for example
           }
        
        }
        

        这具有使用该方法从YourInterface 实现的其他可用类型的优势

        【讨论】:

          猜你喜欢
          • 2016-01-16
          • 2011-07-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-01-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多