Java泛型愚蠢的事情(为什么不能我推断类型?)(Java Generics Silly Thing

2019-09-16 16:39发布

I'll尽量短的问题没有得到回答很。 对于长的解释,这种情况介绍后去。

我会告诉什么我试着去做。 像这样的东西(infering从构造函数传入的类型,才能在另一种方法getLeaderHerd作为返回类型使用它)...:

public class ZooCage{

    private CageFamily<T> inhabitants;  

    public <T>ZooCage(CageFamily<T> herd) {
        this.inhabitants=herd;      
    }

    public T getHerdLeader() {
        return inhabitants.getLeader();
    }   
}

或这个

public class ZooCage{

    private (Type) T;   

    public ZooCage(CageFamily<T> herd) {
        this.T=T;       
    }

    public T getHerdLeader() {
        return inhabitants.getLeader();
    }   
}

所以我可以从主调用类似:

ZooCage cage = new ZooCage(new CageFamily<Lion>()); //Imagine new CageFamily its not empty
Lion leader = cage.getHerdLeader();

即使它不可能,我为什么要认为这是不合理的功能? 它的类型安全的,如果编译器是智能的,少的冗余度,typifiing类ZooCage这是没有必要的

I,M使用泛型特定行为评估。 我设法得到它的工作,但我不知道,不懂为什么不能我推断从ARG类型。 所以我创造了这个例子运行而不与简化的实际结构的目的警告确定。

(直接看最后2行片断的快速简报)

假设我有这两个类。 目标之一:

package Zoo;
import Zoo.Main.CageFamily;
import Zoo.Main.Vertebrate;

public class ZooCage<T extends Vertebrate>{

    private CageFamily<T> inhabitants;  

    public ZooCage(CageFamily<T> herd) {
        this.inhabitants=herd;      
    }

    public T getHerdLeader() {
        return inhabitants.getLeader();
    }   
}

试想一下,在笼子里只能有脊椎动物(昆虫/ aracnids并不大昂巨头quids /章鱼需要水介质)

另外一类,Main.java

package Zoo;
import java.util.ArrayList;

public class Main {

    public static void main(String[] args){
        new Main().test();
    }

    public void test(){
        CageFamily<Lion> lionsHerd = new CageFamily<Lion>();
        lionsHerd.add(new Lion("Simba"));
        lionsHerd.add(new Lion("Nala"));

        CageFamily<Bear> bearsHerd = new CageFamily<Bear>();
        bearsHerd.add(new Bear("Yogi"));
        bearsHerd.add(new Bear("Boo-boo"));

        ZooCage<Lion> cageLions = new ZooCage<Lion>(lionsHerd);     
        ZooCage<Bear> cageBears = new ZooCage<Bear>(bearsHerd);

        for (ZooCage<?> cage : new ZooCage[]{cageLions,cageBears} ) 
           System.out.println("The leader is "+ cage.getHerdLeader());

    }

    public interface Vertebrate{
        public String toString();
        public int numBones();
    }
    public class Lion implements Vertebrate{
        private String name;
        public Lion (String name){this.name=name;}
        public String toString(){return name + " (who has "+numBones()+" bones)";}
        public int numBones(){return 345;}
    }
    public class Bear implements Vertebrate{
        private String name;
        public Bear (String name){this.name=name;}      
        public String toString(){return name + " (who has "+numBones()+" bones)";}
        public int numBones(){return 658;}
    }
    public class CageFamily<E extends Vertebrate> extends ArrayList<E>{
        final static long serialVersionUID = 1L;
        public E getLeader(){
             return get(0); //Let,s assume the first added is the leader
        }
    }
}

这将编译OK并打印

The leader is Simba (who has bones)
The leader is Yogi (who has bones)

什么我想知道的是:有什么办法(仅使用类型/仿制药,没有supressingWarnings也不铸件),以避免该类ZooCage的典型化作为一个整体? 我想一千种从ZooCage,构造器ARG为getHerdLeader返回值获取类型的推断。 它应该是没有必要的典型化ZooCage时,他构造带有预期的类型。 似乎是多余的,让你不必预先知道的类型!

非常感谢所有谁可以帮助!

Answer 1:

Java 7的让你做ZooCage<Type> = new ZooCage<>(argument) 。 这个功能是Java 7新的,不过,是不是在早期版本的Java使用。

或者,围绕Java 6的缺乏类型推断得到的一种传统方式是写一个工厂方法

public static <T> ZooCage<T> newZooCage() {
  return new ZooCage<T>();
}

然后newZooCage()得到它的类型自动推断,因为即使Java 5的有类型推断的方法 -只要不是构造函数。



Answer 2:

Java不支持类型推断。

如果你的兴趣,你应该看看斯卡拉。

在Java 7中,可以ommit在右手侧之间<>类型。 在Java 6中,您可以用番石榴静态方法做到这一点 。 Java的8可/将有文字(或至少检查一次),这样也可以帮助。

我不同意任何这些都是真正的类型推断 (见下面的评论)。



文章来源: Java Generics Silly Thing (Why cant I infer the type?)