Java泛型愚蠢的事情(为什么我不能推断这种类型?) [英] Java Generics Silly Thing (Why cant I infer the type?)

查看:516
本文介绍了Java泛型愚蠢的事情(为什么我不能推断这种类型?)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于问题没有得到很好的回答,我会尽量缩短。对于长时间的解释,请参阅本简报。



我将展示我正在尝试做什么。像这样的东西(从构造函数中推断传入的类型,以便在另一个方法getLeaderHerd中使用它作为返回类型)...:

  public class ZooCage {

private CageFamily< T>居民;

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

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


$ / code $ / pre

b $ b

  public class ZooCage {

private(Type)T;

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

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






$ b

所以我可以从Main调用类似于 p>

  ZooCage笼子=新的ZooCage(新的CageFamily< Lion>()); //想象一下新的CageFamily它不是空的
Lion leader = cage.getHerdLeader();

即使不可能,为什么我认为这不合理?它的类型安全,如果编译器是智能的并且没有多余的类型ZooCage,这是不必要的。



I,m使用泛型对特定行为进行评估。我设法得到它的工作,但我不明白为什么不能从arg中推断出这种类型。所以我创建了这个示例,它可以在没有警告的情况下正常运行,以简化实际的体系结构。



(请直接看最后一个2行代码片段进行快速简报)

假设我得到了这两个类。目标之一:

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

public class ZooCage< T extends Vertebrate> {

private CageFamily< T>居民;

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

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






$ b

想象一下,在笼子里只能有脊椎动物(昆虫/ aracnids是不是要大的ang巨人quids /章鱼需要水生中等)

另一个类Main.java

  package Zoo; 
import java.util.ArrayList;
$ b $ public class Main {

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

public void test(){
CageFamily< Lion> lionsHerd =新的CageFamily< Lion>();
lionsHerd.add(新狮子(Simba));
lionsHerd.add(新狮子(Nala));

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

ZooCage< Lion> cageLions = new ZooCage< Lion>(lionsHerd);
ZooCage< Bear> cageBears = new ZooCage< Bear>(bearsHerd); (ZooCage<>笼子:新ZooCage [] {cageLions,cageBears})
System.out.println(The leader is+ cage.getHerdLeader());





public interface脊椎动物{
public String toString();
public int numBones();
}
public class Lion实现了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>扩展ArrayList< E> {
final static long serialVersionUID = 1L;
public E getLeader(){
return get(0); //让我们假设第一个添加的是领导
}
}
}

这个编译好并打印出来

 领导是Simba(有骨头)
领导者是瑜珈(有骨头)

我想知道的是:有没有办法(只使用类型/泛型和没有抑郁的警告和铸件),以避免类ZooCage作为一个整体的典型?我尝试了几千种方法来从ZooCage的构造函数arg中得到对getHerdLeader的返回值的推断。当他的构造函数带有预期类型时,应该没有必要对ZooCage进行典型化。看起来多余,让你必须事先知道类型!



非常感谢所有可以帮助的人!

ZooCage< Type> =新的ZooCage<>(参数)。这个特性在Java 7中是新的,但在Java的早期版本中是不可用的。另外,传统的避开Java 6缺乏类型推断的方式是编写一个工厂方法

  public static< T> ZooCage< T> newZooCage(){
返回新的ZooCage< T>();

$ / code>

,然后 newZooCage()自动推断它的类型,因为即使Java 5对方法进行了类型推断 - 只是对于构造函数而言。


I´ll try to be short as the question has not been very answered. For the long explanation, go after this briefing.

I will show what Im trying to do. Something like this (infering the incoming type from the constructor in order to use it in another method getLeaderHerd as a return type)... :

public class ZooCage{

    private CageFamily<T> inhabitants;  

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

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

or this

public class ZooCage{

    private (Type) T;   

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

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

so I could call from Main something like:

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

Even if its not possible, why should I think that that is not reasonable to feature? Its type safe if the compiler is intelligent and less redundant that typifiing the class ZooCage which is not necessary

I,m assessing using Generics for a particular behavior. I managed to get it work but I don,t understand why cant I infer the type from the arg. So I created this example which runs ok without warnings with the purpose of simplifying the actual architecture.

( Look directly the last 2-lines snippet for a fast briefing )

Suppose I got these two classes. The target one:

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

Imagine that in cages there can only be Vertebrates (Insects/aracnids are not to big ang giant quids/octopus needs aquatic medium)

The other one class, 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
        }
    }
}

This compiles OK and prints

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

What Im wondering is: Is there any way (only using types/generics and without supressingWarnings nor castings) to avoid the typification of the class ZooCage as a whole? I tried thousand ways to get the inference of the type from ZooCage,s constructor arg to the return value for getHerdLeader. It should be not necessary typifying ZooCage when his constructor comes with the expected type. Seems redundant and makes you having to know beforehand the type!

Thank you very much to all who can help!

解决方案

Java 7 lets you do ZooCage<Type> = new ZooCage<>(argument). That feature is new in Java 7, though, and isn't available in earlier versions of Java.

Alternately, a traditional way of getting around Java 6's lack of type inference is to write a factory method

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

and then newZooCage() gets its type automatically inferred, since even Java 5 had type inference for methods -- just not for constructors.

这篇关于Java泛型愚蠢的事情(为什么我不能推断这种类型?)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆