Java 如何使用Class<;T>;在爪哇?

Java 如何使用Class<;T>;在爪哇?,java,templates,class,generics,Java,Templates,Class,Generics,关于泛型和它们在后台的真正作用有一个很好的讨论,所以我们都知道Vector是整数数组的向量,HashTable是一个表,其键是字符串和值Persons。 然而,让我感到困惑的是Class的用法 java类class也应该使用一个模板名(eclipse中的黄色下划线告诉我)。我不明白我应该在里面放什么。类对象的全部意义在于,当您没有关于对象的全部信息时,例如反射等。为什么它让我指定类对象将包含哪个类?我显然不知道,或者我不会使用类对象,我会使用特定的对象。来自Java文档: [……] 更令人惊讶的

关于泛型和它们在后台的真正作用有一个很好的讨论,所以我们都知道
Vector
是整数数组的向量,
HashTable
是一个表,其键是字符串和值
Person
s。 然而,让我感到困惑的是
Class
的用法


java类
class
也应该使用一个模板名(eclipse中的黄色下划线告诉我)。我不明白我应该在里面放什么。
对象的全部意义在于,当您没有关于对象的全部信息时,例如反射等。为什么它让我指定
对象将包含哪个类?我显然不知道,或者我不会使用
对象,我会使用特定的对象。

来自Java文档:

[……] 更令人惊讶的是,类被泛化了。类文本现在充当类型标记,提供运行时和编译时类型信息。这将启用一种静态工厂样式,以新AnnotatedElement界面中的getAnnotation方法为例:

<T extends Annotation> T getAnnotation(Class<T> annotationType); 
在使用泛型之前,您必须将结果转换为Author。此外,您也无法让编译器检查实际参数是否表示注释的子类。[……]


我从来不用用这种东西。有人吗?

使用类的泛化版本,除其他外,还可以编写如下内容

Class<? extends Collection> someCollectionClass = someMethod();

Class您通常希望在
Class
中使用通配符。例如,
Class正如其他答案所指出的,这个
Class
是通用的,有很多很好的理由。但是,在很多情况下,您无法知道要与
类一起使用的泛型类型。在这些情况下,您可以简单地忽略黄色的eclipse警告,或者使用
Class
。。。我就是这样做的;)

我发现创建服务注册表查找时,
class
很有用。例如

<T> T getService(Class<T> serviceClass)
{
    ...
}
T获取服务(类服务类)
{
...
}

一开始就让人困惑。但在以下情况下它会有所帮助:

class SomeAction implements Action {
}

// Later in the code.
Class<Action> actionClass = Class.forName("SomeAction"); 
Action action = actionClass.newInstance();
// Notice you get an Action instance, there was no need to cast.
类SomeAction实现操作{
}
//代码的后面部分。
Class actionClass=Class.forName(“SomeAction”);
Action Action=actionClass.newInstance();
//注意,如果您得到一个动作实例,则无需强制转换。

在@Kire Haglin的回答之后,可以在以下内容中看到泛型方法的进一步示例:

public T unmarshal(类docClass,InputStream-InputStream)
抛出异常{
字符串packageName=docClass.getPackage().getName();
JAXBContext jc=JAXBContext.newInstance(packageName);
解组器u=jc.createUnmarshaller();
JAXBElement doc=(JAXBElement)u.unmarshal(inputStream);
返回doc.getValue();
}

这允许
unmarshal
返回任意JAXB内容树类型的文档。

只需使用beef类:

public <T> T beefmarshal( Class<beef> beefClass, InputBeef inputBeef )
     throws JAXBException {
     String packageName = docClass.getPackage().getBeef();
     JAXBContext beef = JAXBContext.newInstance( packageName );
     Unmarshaller u = beef.createBeef();
     JAXBElement<T> doc = (JAXBElement<T>)u.beefmarshal( inputBeef );
     return doc.getBeef();
}
public T beefmarshal(类beefClass,输入牛肉输入牛肉)
抛出异常{
字符串packageName=docClass.getPackage().getBeef();
JAXBContext=JAXBContext.newInstance(packageName);
Unmarshaller u=beef.createBeef();
JAXBElement doc=(JAXBElement)u.beefmarshal(inputBeef);
返回doc.getBeef();
}
我们只知道“任何类的所有实例都共享该类类型的相同java.lang.class对象”

e、 (g)

然后
a.getClass()==b.getClass()
为真

现在假设

Teacher t = new Teacher();
如果没有泛型,下面的内容是可能的

Class studentClassRef = t.getClass();
但现在这是错误的

e、 g)
public void printStudentClassInfo(Class studentClassRef){}
可以通过
Teacher.Class调用

使用泛型可以避免这种情况

Class<Student> studentClassRef = t.getClass(); //Compilation error.
这里T可用作
String
类型,如CarName

或T可用作
整数
类型,如型号

或者T可以用作
对象
类型作为有效汽车实例

现在,上面是一个简单的POJO,它可以在运行时以不同的方式使用。
集合(例如)List、Set、Hashmap是根据T的声明处理不同对象的最佳示例,但一旦我们将T声明为String
e.g)
HashMap=newhashmap()则它将只接受字符串类实例对象

通用方法

泛型方法是引入自己类型参数的方法。这类似于声明泛型类型,但类型参数的作用域仅限于声明它的方法。允许使用静态和非静态泛型方法以及泛型类构造函数

泛型方法的语法包括一个类型参数,位于尖括号内,并显示在方法的返回类型之前。对于泛型方法,类型参数部分必须出现在方法的返回类型之前

 class Util {
    // Generic static method
    public static <K, V, Z, Y> boolean compare(Pair<K, V> p1, Pair<Z, Y> p2) {
        return p1.getKey().equals(p2.getKey()) &&
               p1.getValue().equals(p2.getValue());
    }
}

 class Pair<K, V> {

    private K key;
    private V value;
}
但下面是错误的,因为类级类型参数K、V、Z和Y不能在静态上下文中使用(这里是静态方法)

class-Util{
//通用静态法
公共静态布尔比较(对p1,对p2){
返回p1.getKey().equals(p2.getKey())&&
p1.getValue().equals(p2.getValue());
}
}
其他有效场景为

class MyClass<T> {

        //Type declaration <T> already done at class level
        private  T myMethod(T a){
            return  a;
        }

        //<T> is overriding the T declared at Class level;
        //So There is no ClassCastException though a is not the type of T declared at MyClass<T>. 
        private <T> T myMethod1(Object a){
                return (T) a;
        }

        //Runtime ClassCastException will be thrown if a is not the type T (MyClass<T>).  
        private T myMethod1(Object a){
                return (T) a;
        }       

        // No ClassCastException        
        // MyClass<String> obj= new MyClass<String>();
        // obj.myMethod2(Integer.valueOf("1"));
        // Since type T is redefined at this method level.
        private <T> T myMethod2(T a){
            return  a;
        }

        // No ClassCastException for the below
        // MyClass<String> o= new MyClass<String>();
        // o.myMethod3(Integer.valueOf("1").getClass())
        // Since <T> is undefined within this method; 
        // And MyClass<T> don't have impact here
        private <T> T myMethod3(Class a){
            return (T) a;
        }

        // ClassCastException for o.myMethod3(Integer.valueOf("1").getClass())
        // Should be o.myMethod3(String.valueOf("1").getClass())
    private  T myMethod3(Class a){
        return (T) a;
    }


        // Class<T> a :: a is Class object of type T
        //<T> is overriding of class level type declaration; 
        private <T> Class<T> myMethod4(Class<T> a){
            return  a;
        }
    }
class-MyClass{
//类型声明已在类级别完成
私有T myMethod(T a){
返回a;
}
//重写在类级别声明的T;
//因此没有ClassCastException,尽管a不是MyClass中声明的T类型。
私有T myMethod1(对象a){
返回(T)a;
}
//如果a不是类型T(MyClass),则将引发运行时ClassCastException。
私有T myMethod1(对象a){
Class<Student> studentClassRef = t.getClass(); //Compilation error.
/**
 * Generic version of the Car class.
 * @param <T> the type of the value
 */
public class Car<T> {
    // T stands for "Type"
    private T t;

    public void set(T t) { this.t = t; }
    public T get() { return t; }
}
 class Util {
    // Generic static method
    public static <K, V, Z, Y> boolean compare(Pair<K, V> p1, Pair<Z, Y> p2) {
        return p1.getKey().equals(p2.getKey()) &&
               p1.getValue().equals(p2.getValue());
    }
}

 class Pair<K, V> {

    private K key;
    private V value;
}
class MyClass<T> {
   private  T myMethod(T a){
       return  a;
   }
}
class Util <K, V, Z, Y>{
    // Generic static method
    public static  boolean compare(Pair<K, V> p1, Pair<Z, Y> p2) {
        return p1.getKey().equals(p2.getKey()) &&
               p1.getValue().equals(p2.getValue());
    }
}
class MyClass<T> {

        //Type declaration <T> already done at class level
        private  T myMethod(T a){
            return  a;
        }

        //<T> is overriding the T declared at Class level;
        //So There is no ClassCastException though a is not the type of T declared at MyClass<T>. 
        private <T> T myMethod1(Object a){
                return (T) a;
        }

        //Runtime ClassCastException will be thrown if a is not the type T (MyClass<T>).  
        private T myMethod1(Object a){
                return (T) a;
        }       

        // No ClassCastException        
        // MyClass<String> obj= new MyClass<String>();
        // obj.myMethod2(Integer.valueOf("1"));
        // Since type T is redefined at this method level.
        private <T> T myMethod2(T a){
            return  a;
        }

        // No ClassCastException for the below
        // MyClass<String> o= new MyClass<String>();
        // o.myMethod3(Integer.valueOf("1").getClass())
        // Since <T> is undefined within this method; 
        // And MyClass<T> don't have impact here
        private <T> T myMethod3(Class a){
            return (T) a;
        }

        // ClassCastException for o.myMethod3(Integer.valueOf("1").getClass())
        // Should be o.myMethod3(String.valueOf("1").getClass())
    private  T myMethod3(Class a){
        return (T) a;
    }


        // Class<T> a :: a is Class object of type T
        //<T> is overriding of class level type declaration; 
        private <T> Class<T> myMethod4(Class<T> a){
            return  a;
        }
    }
public static <T extends Enum<T>>Optional<T> optionalFromString(
        @NotNull Class<T> clazz,
        String name
) {
    return Optional<T> opt = Optional.ofNullable(name)
            .map(String::trim)
            .filter(StringUtils::isNotBlank)
            .map(String::toUpperCase)
            .flatMap(n -> {
                try {
                    return Optional.of(Enum.valueOf(clazz, n));
                } catch (Exception e) {
                    return Optional.empty();
                }
            });
}
public class Shape<T> {
    // T stands for "Type"
    private T t;

    public void set(T t) { this.t = t; }
    public T get() { return t; }
}
Shape<Integer> s1 = new Shape();
Shape<String> s2 = new Shape();