Custom Generics解释

时间:2011-01-17 13:39:40

标签: java generics interface java-ee

请在java界面中解释自定义'T'。它在这里使用泛型,我想是'T'类型。然后在哪里定义'T'类型?

  public interface TemplateBuilder<T extends TemplateBuilder>  

4 个答案:

答案 0 :(得分:7)

T不是实际的课程。它在编译时确定,具体取决于您的类TemplateBuilder的用法。只需将其视为各种可能类型的占位符,其中一种根据您的具体情况“选择”。

有关更简单的示例,请查看以下内容(改编自Java教程):

想象一下,你想要声明一个类Box,它可以采用特定类型(该对象保存在框内),但是你希望在各种情况下重用它来保存各种不同的类型。

因此,不是修复Box可以采用的实际类型,而是声明如下:

public class Box<T> {

    private T t; // T stands for "Type"          

    public void set(T t) {
        this.t = t;
    }

    public T get() {
        return t;
    }
}

当您使用它时,您可以执行以下操作:

Box<Integer> integerBox = new Box<Integer>();

你可能要问的重点是什么?为什么不让Box拿一个对象?

事实上,在Java 1.5之前,这是不可能的。这被引入以在这些情况下具有进一步的类型安全性,并且在集合框架中被采用。

重点是没有这种机制,如果它使用了Object,则不能强制Box的特定实例仅保存Integers。另一方面,如果你使用专门的Integers,你不能重复使用Box for String或其他对象,你需要创建另一种类型的Box类。

在Java 1.5之前,像ArrayList这样的对象使用了普通的对象,但是在运行时经常会出现类型安全性损坏的情况,因为程序假设是一个Integer对象列表,而在某处插入了一个String。泛型(通过这个神奇的T)强制类型而不限制它们可能是什么。

在你的情况下,T extends TemplateBuilder更进一步说明无论T是什么,它都必须是一个扩展TemplateBuilder的类。如果不存在,那么任何扩展Object的类(Java的通用基类)。

答案 1 :(得分:1)

T是从Object

延伸的任何TemplateBuilder

T表示任何对象。例如

List<T> list = new ArrayList<T>();

此处T可以是IntegerString ...

<T extends A>表示任何Object T都来自A

答案 2 :(得分:1)

在实现接口时定义了这种类型,即

class StringBuilder implements TemplateBuilder<StringBuilder> {}

BTW,请参阅类Enum(所有枚举的基类)。

答案 3 :(得分:0)

我的自定义泛型说明

Backgorund:

  1. 自定义泛型总是与数据结构一起使用,例如:管理(存储/检索)&#34;事物&#34;
  2. 的列表时
  3. 需要进行自己的类型检查,以便编译代码,因为自定义泛型包含多态性原则。
  4. 然而,与传统的&#34;相反。多态性的OO原则,一个类可以存储一些没有的事物列表,其中包含任何关系&#34;&#34;&#34;它是存储(OO的基本原理,其中A不是B级的超类)
  5. 你没有为每一种类型的东西制作单独的子类。&#34;东西&#34;你想存放。
  6. 示例1

    作为示例,请考虑以下两个类无关。这是一个非常原始的例子,但是给出了自定义泛型原理的概述:

    /**
     *
     * Class A is a Custom Generic class that can be 'typed'
     * to any kind of class using diamond 'T' syntax. 
     * 
     */
    
    class A<T> 
    {   
      // The instance variable of the object type 'T' known at run time
      T theI;
    
      // The constructor passing the object type 'T' 
      A(T anI)
      {
        this.theI = anI;
      }
    
      // Method to return the object 'T'
      T getT()
      {
        return theI;
      }
    }  
    

    以下是与A类无关的B类,即B不延伸A:

    /**
    *
    * Simple class which overrides the toString()
    * method from Object's class toString() method 
    * 
    */
    class B 
    {
    
      @Override
      public String toString()
      {
        return "B Object";
      }
    
      public static void main(String[] args)
      {
        A<B> a = new A<>(new B());
    
        System.out.println(a.getT());        
      }
    }
    

    在上面B类的主要方法中:

    a.getT()返回对象&#39; T&#39;在这个例子中属于&#39; B&#39; (这是多态的一个例子)。

    a.getT()返回对象&#39; T&#39;对象实例C的方法toString()被隐式调用,因为它覆盖了对象的toString()方法并打印&#34; B对象&#34;。

    关于Custom Generics和polymorphism的有趣方面是:

    在自定义泛型的上下文中,为了执行多态,类之间存在没有约束关系

    e.g。 B类无关到A以上,即B类不延伸 A.

    &#34; 传统&#34;面向对象的多态性原则,对于以某种方式相关的类总是有一个要求约束。但是,自定义泛型中不需要这样做。

    示例2

    public interface TemplateBuilder<T extends TemplateBuilder>
    

    上述意味着TemplateBuilder界面可以 键入 扩展 TemplateBuilder的任何类。

    假设SomeClass扩展了TemplateBuilder,那么下面就可以了:

    TemplateBuilder<SomeClass> tbRef = ... 
    /* Using an Anonymous Inner Class reference to interface TemplateBuilder<SomeClass> */ 
    

    TemplateBuilder<SomeClass> tbRef = .... /*  Referencing a concrete class 
    that implements TemplateBuilder */