代码之家  ›  专栏  ›  技术社区  ›  nanda

使用显式类型参数调用静态导入的方法

  •  24
  • nanda  · 技术社区  · 15 年前

    以下是我问题的后续步骤: Weird Java generic .

    如果我有这样的代码:

    Casts.<X, T> cast(iterable[index]);
    

    我可以添加静态导入并执行以下操作吗:

    <X, T> cast(iterable[index]);
    

    Eclipse不允许这样做。但是在Eclipse中看到这么多静态导入的bug之后,我就不那么确定了。

    5 回复  |  直到 8 年前
        1
  •  9
  •   bernard paulus    8 年前

    不,你不能:我刚通过一些测试代码确认了这一点。

    PS > javac -version
    javac 1.6.0_04
    

    爪哇

    public class Casts
    {
        public static <From, To> To cast(final From object)
        {
            return (To)object;
        }
    }
    

    测试.java

    import static Casts.cast;
    
    public class Test
    {
        public static void main(String[] args)
        {
            final Integer integer = new Integer(5);
    
            // This one compiles fine.
            final Number number = Casts.<Integer, Number>cast(integer);
    
            // This one fails compilation:
            // PS> javac Test.java
            // Test.java:11: illegal start of expression
            //             final Number number = <Integer, Number>cast(integer);
            //                                                    ^
            // Test.java:11: not a statement
            //             final Number number = <Integer, Number>cast(integer);
            //                                                        ^
            final String string = <Integer, String>cast(integer);
        }
    }
    
        2
  •  7
  •   Dónal    15 年前

    如果要在调用泛型静态方法时提供显式类型参数,则必须在该方法前面加上类名,即使该方法是静态导入的。

        3
  •  3
  •   Tibor Blenessy    10 年前

    Java语法只允许指定类型名的类型参数。参见JLS中的相应章节 https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-MethodInvocation

        4
  •  2
  •   Jonathan Weatherhead    14 年前

    据我所读,静态导入机制的一个缺点是,如果您希望提供形式参数,那么必须指定调用对象/类。在本例中,不太清楚为什么有两个泛型参数,但如果您希望避免指定调用对象/类,则可以通过参数转换键入hint,例如:

    public static <E> E foo(E e) {}
    
    Number n = foo((Number)3);
    

    有了类型提示,类型推断将返回一个类型为number的对象,而不是integer,否则它将返回一个类型为number的对象。

        5
  •  1
  •   Matthew Flynn    15 年前

    我敢肯定答案是否定的——如果你想使用一个通用方法调用,你需要一个对象来调用它。( foo.<T>doSomething() )如果方法是静态的,则需要类( Foo.<T>doSomething() )

    如果您从类本身的其他地方调用方法,这甚至是正确的。如果您使用的是非静态方法(即实例方法),那么您将调用 this.<T>doSomething() .