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();