在Java中,我想有如下的东西:

class Clazz<T> {
  static void doIt(T object) {
    // ...
  }
}

但是我知道

Cannot make a static reference to the non-static type T

除了基本用途之外,我不了解泛型,因此无法理解它。我在网上找不到很多关于这个主题的信息,这也无济于事。

有人能澄清一下这种使用是否可能,以类似的方式?还有,为什么我最初的尝试失败了?


当前回答

在声明doIt()方法时,可以使用泛型方法的语法来做你想做的事情(注意doIt()方法签名中的static和void之间添加了<T>):

class Clazz<T> {
  static <T> void doIt(T object) {
    // shake that booty
  }
}

我让Eclipse编辑器接受上面的代码,没有Cannot make a static reference to the non-static type T错误,然后将其扩展到以下工作程序(完成一些适合年龄的文化引用):

public class Clazz<T> {
  static <T> void doIt(T object) {
    System.out.println("shake that booty '" + object.getClass().toString()
                       + "' !!!");
  }

  private static class KC {
  }

  private static class SunshineBand {
  }

  public static void main(String args[]) {
    KC kc = new KC();
    SunshineBand sunshineBand = new SunshineBand();
    Clazz.doIt(kc);
    Clazz.doIt(sunshineBand);
  }
}

当我运行它时,它将这些行打印到控制台:

抖抖那个“战利品”类com.eclipseoptions.datamanager。Clazz KC美元”! ! 抖抖那个“战利品”类com.eclipseoptions.datamanager。Clazz SunshineBand美元”! !

其他回答

直到实例化一个类型,Java才知道T是什么。

也许你可以通过调用Clazz<T>.doit(一些东西)来执行静态方法,但听起来你不能。

另一种处理方法是将类型参数放在方法本身中:

static <U> void doIt(U object)

这并不能让你对U有正确的限制,但总比没有好....

在声明doIt()方法时,可以使用泛型方法的语法来做你想做的事情(注意doIt()方法签名中的static和void之间添加了<T>):

class Clazz<T> {
  static <T> void doIt(T object) {
    // shake that booty
  }
}

我让Eclipse编辑器接受上面的代码,没有Cannot make a static reference to the non-static type T错误,然后将其扩展到以下工作程序(完成一些适合年龄的文化引用):

public class Clazz<T> {
  static <T> void doIt(T object) {
    System.out.println("shake that booty '" + object.getClass().toString()
                       + "' !!!");
  }

  private static class KC {
  }

  private static class SunshineBand {
  }

  public static void main(String args[]) {
    KC kc = new KC();
    SunshineBand sunshineBand = new SunshineBand();
    Clazz.doIt(kc);
    Clazz.doIt(sunshineBand);
  }
}

当我运行它时,它将这些行打印到控制台:

抖抖那个“战利品”类com.eclipseoptions.datamanager。Clazz KC美元”! ! 抖抖那个“战利品”类com.eclipseoptions.datamanager。Clazz SunshineBand美元”! !

T不在静态方法的范围内,因此不能在静态方法中使用T。您需要为静态方法定义一个不同的类型参数。我会这样写:

class Clazz<T> {

  static <U> void doIt(U object) {
    // ...
  }

}

例如:

public class Tuple<T> {

    private T[] elements;

    public static <E> Tuple<E> of(E ...args){
        if (args.length == 0) 
             return new Tuple<E>();
        return new Tuple<E>(args);
    }

    //other methods
}

不能在静态方法或静态字段中使用类的泛型类型参数。类的类型参数只在实例方法和实例字段的范围内。对于静态字段和静态方法,它们在类的所有实例之间共享,甚至是不同类型参数的实例,因此显然它们不能依赖于特定的类型参数。

您的问题似乎不需要使用类的类型参数。如果你能更详细地描述你想要做的事情,也许我们可以帮助你找到更好的方法。

当您为类指定泛型类型时,JVM只知道它是类的实例,而不是定义。每个定义只有参数化类型。

泛型的工作方式类似于c++中的模板,因此您应该首先实例化类,然后使用指定类型的函数。