Java泛型:实际参数T不能通过方法调用转换转换为int

Gen*_*rin 15 java generics

我有这样的代码:

// This class cannot be changed
class VendorApi {
        static void func1(char x) {}
        static void func1(int x) {}
        static void func1(float x) {}
        static void func1(double x) {}
}

class Main {
          static <T> void my_func(T arg) {
                  // much of code, which uses T
                  // ...
                  VendorApi.<T>func1(arg);
          }

          public static void main(String args[]) {
                  // call my_func for each type (char, int, float, double)
                  // ...
                  int i = 1;
                  my_func(i);
                  char c = 1;
                  my_func(c);
          }
}
Run Code Online (Sandbox Code Playgroud)

我需要做的是从my_func()为每种类型的参数调用每个函数VendorApi.func().发布的代码没有编译,它显示了一个想法.除了为每种类型复制粘贴my_func()之外,我该怎么做呢?

Ale*_*lex 6

您可以func1将此方法作为Consumer<T>:

class VendorApi {
    static void func1(char x) {}
    static void func1(int x) {}
    static void func1(float x) {}
    static void func1(double x) {}
}

class Main {
      static void my_func(char arg) {  my_func(arg, VendorApi::func1); }
      static void my_func(int arg) {  my_func(arg, VendorApi::func1); }
      static void my_func(float arg) {  my_func(arg, VendorApi::func1); }
      static void my_func(double arg) {  my_func(arg, VendorApi::func1); }
      private static <T> void my_func(T arg, Consumer<T> func1) {
          // much of code, which uses T
          // ...
          func1.accept(arg);
      }

      public static void main(String args[]) {
          // call my_func for each type (char, int, float, double)
          // ...
          int i = 1;
          my_func(i, VendorApi::func1);
          char c = 1;
          my_func(c);
      }
}
Run Code Online (Sandbox Code Playgroud)

这给你编译时类型安全(你只能叫my_funcchar,int,floatdouble,避免反射从外部类,因为通用的版本是私有的).

如果要遵循Java方法命名约定,也my_func应该如此myFunc.


Nie*_*len 4

这不是最干净的答案,但它会按照你的要求做。

您可以测试您的泛型参数类是否与您提供的任何类型匹配VenderApi,然后进行强制转换。

代码

public class Main {
    static <T> void my_func(T arg) {
        if (arg.getClass().equals(Integer.class))
            VendorApi.func1((Integer) arg);
        else if (arg.getClass().equals(Character.class))
            VendorApi.func1((Character) arg);
        else
            throw new IllegalStateException(
                    "cannot perform my_func on object of class "
                            + arg.getClass());
    }

    public static void main(String args[]) {
        // call my_func for each type (char, int, float, double)
        // ...
        int i = 1;
        my_func(i);
        char c = 1;
        my_func(c);
        String str = "bla";
        my_func(str);
    }
}
Run Code Online (Sandbox Code Playgroud)

您的供应商 API

//This class cannot be changed
public class VendorApi {
    public static void func1(char x) {
        System.out.println("i am a char "+x);
    }

    public static void func1(int x) {
        System.out.println("i am a int "+x);
    }

    public static void func1(float x) {
    }

    public static void func1(double x) {
    }
}
Run Code Online (Sandbox Code Playgroud)

输出

i am a int 1
i am a char 
Exception in thread "main" java.lang.IllegalStateException: cannot perform my_func on object of class class java.lang.String
    at core.Main.my_func(Main.java:10)
    at core.Main.main(Main.java:23)
Run Code Online (Sandbox Code Playgroud)

  • @GennadyProskurin,这意味着您需要重构`my_func`,使其成为一行,并且“相同的代码片段”位于其他函数中:)。最大的问题实际上不是这个,而是这个实现不是类型安全的。您不希望泛型函数抛出运行时异常,抱怨类型错误,因为它完全违背了泛型的目的,您也可以将其声明为“my_func(Object arg)”。 (2认同)
  • 你应该真正使用“instanceof”,而不是“getClass().equals()”,它优化得更好,而且更短。 (2认同)