java泛型中的自限定类型有什么作用

java泛型中的自限定类型有什么作用?具体举个例子,一个应用场景

@caozhy 给出了限定类型泛型的作用,即,限制类型参数的范围,同时可以使用限定的界限包含的方法。比如caozhy提出的例子调整成可用的形式:

    public static <T extends Number> void sort(List<T> col) {
        for (int i = 0; i < col.size() - 1; i++)
            for (int j = i; i < col.size() - 1; j++) {
                if (col.get(j).longValue() > col.get(j + 1).longValue()) {//可以直接使用Number的方法
                    // 交换
                }
            }
    }

什么样的是自限定类型呢?即,限定范围就是自身。比如一个实现了Comparable接口的的User类,希望只能和User类的实例进行比较,那么我们需要这样写:

    static class User2 implements Comparable<User2>{
        public int compareTo(User2 o) {
            //
        }   
    }

这样就利用了限定类型的两个用处:1.限定范围;2.可以使用限定类的方法。另外一个点,就是限定了只能是同类型的进行比较。

我们再来看一个更复杂的,jdk里的Enum类定义:

 public abstract class Enum<E extends Enum<E>>
        implements Comparable<E>, Serializable{
}

这是一个更复杂的限定类型,为什么要这么复杂呢?如果我们写成简单的样子行不行?像这样:

 public abstract class Enum
        implements Comparable<Enum>, Serializable{
}

(关于Enum类和子类之间的关系,可以参考这里:https://www.cnblogs.com/ly-radiata/articles/6049822.html)
不是同样可以起到限定范围在Enum类么?为什么又要多次一举,弄得这么复杂?
这和Enum类的作用有关系,Enum这个抽象类是用来被继承的,所以我们总是在定义和使用Enum的子类,而且我们希望enum Day和enum Month只能自己的枚举值之间进行比较,而不能互相比较。比如Monday和January就不能比较,因为比较是没有意义的。

看明白了这里,我们再来看一下,简化了的Enum能不能达到上述的限制目的?

 class Day extends Enum{
 }

 class Month extends Enum{
 }

 public satic void main(String[] args){
     Day monday = new Day("monday");
         Month january = new Month("january");
     monday.compareTo(january);// 1
 }

上述1位置的compareTo方法,在简化的Enum情况下是可以的,但是在jdk中复杂的Enum下是不可以的。这也就是为什么jdk里的Enum要定义的这么复杂,目的就是为了限制Enum的子类只能和自己同类的实例进行比较。

说的浅显一点,就是更加明确使用的对象.更方便调用.
不然如果定一下成Object的话.还需要进行一步强转在继续使用

自限定所做的就是要求在继承关系中,强制要求将正在定义的类当做参数传递给基类。可以保证类型参数必须与正在被定义的类相同:
1.提高了可读性,一看便知道里面放的是什么。
2.提高了安全性,防止对象的转换出错。

class SelfBounded>{

T element;

SelfBounded set(T arg){

element=arg;

return this;

}

T get(){return element;}

}

class A extends SelfBounded{}

class B extends SelfBounded
{}

class C extends SelfBounded{

C setAndGet(C arg){

set(arg);

return get();

}

}

class D{}

//因为类D没有继承SelfBounded,所以该类编译失败。

//class E extends SelfBounded{}

class SelfBounding {

public static void main(String[] args) {

A a=new A();

a.set(new A());

a=a.set(new A()).get();

a=a.get();

C c=new C();

c=c.setAndGet(new C());

}

}

最重要的是限定泛型的类型,以便为泛型的调用者提供更精确的编译能力。

比如说,你写了一个泛型类型的排序。
void sort(Collection col)
显然作为排序,你的程序需要比较两个元素的大小,来确定它们的相对关系。
比如

 void sort<T>(Collection<T> col)
{
for (int i = 0; i < col.size() - 1; i++)
for (int j = i; i < col.size() - 1; j++)
{
if (比较 col.get(j) 和 col.get(j + 1))
{
//交换
}
}
}

现在的问题是if (比较 col.get(j) 和 col.get(j + 1))这个怎么写?
也许你想,我们可以写
if (col.get(j).compareTo(col.get(j + 1)))
但是怎么保证传入的元素有compareTo这个方法呢?
你可以将T限定在Compareable接口上。
这样做,编译器可以直接检查传入的T是否实现了这个接口。如果不符合,就不通过编译,而你的程序,直接放心调用就可以了。

你可以反过来想一想如果没有限定类型同样的代码该怎么写,是不是会多写很多方法才能实现,或者写一些很别扭的代码才能实现

如楼上所说,明确对象,方便使用
不然没有泛型用object对象,还要进行装包、拆包或强转操作,没有效率

自己去看官方文档泛型的定义

泛型靠谱的用途就是将运行时期的错误放到了编译时期,避免了类型强转。具体使用你可以看我的一片博文
http://blog.csdn.net/whb3299065/article/details/79105750