在INS中嵌入通用类

时间:2014-07-09 02:32:09

标签: java generics casting type-safety

我知道我们可以通过在java中添加使用Generics来跳过强制转换,如下所示。 (当我们在Generic类之外使用它时。)

但是如果我们在泛型类(T item)中对类型对象(Container<T>)进行一些逻辑,我们应该检查实例并且特意施放不是吗?所以我们可以用它来跳过抛弃泛型类。

请检查public void setItem(T item)方法中的注释代码。

我想知道我的理解是正确的还是我错过了什么

Client.java

    public class Client {

        public static void main(String[] args) {


            // String container
            Container<String>   stringContainer     = new Container<String>();
            stringContainer.setItem("Test");
            //stringContainer.setItem(new StringBuffer("")); // compilation error, type safety checking 

            System.out.println(stringContainer.getItem().toUpperCase()); // No need to cast


            // Integer container
            Container<Integer> integerContainer = new Container<Integer>();
            integerContainer.setItem(123);

            //integerContainer.setItem("123"); // compilation error, type safety checking 

           System.out.println(integerContainer.getItem().intValue()); // No need to cast

        }

    }

容器类

class Container<T> {

    private T item;

    public T getItem(){
        return item;
    }

    public void setItem(T item){

        /* If I' doing some thing on item then I have to check the instance of and cast isn't it?

        if(item instanceof String){
            System.out.println("setItem().((String)item).toUpperCase() : " + ((String) item).toUpperCase());
        }
        */

        this.item = item;
    }
}

参考:http://nandirx.wordpress.com/category/java-2/generics-java/

4 个答案:

答案 0 :(得分:3)

正如其他人所说,你不应该贬低一般类型,因为它会破坏泛型的目的。

您应该使用绑定泛型。绑定泛型允许您要求具有特定类型的泛型。这允许您访问特定类型的值而无需强制转换。

这对于String类没有意义,因为String被标记为final,因此无法扩展,但对于将来,请尝试这样的事情。

public interface Shape{
    double getArea();
}

public class Rectangle implements Shape{
    double width;
    double height;
    public double getArea(){ return width*height;}
}

//this collection can hold Shape, or any type implementing shape.
public class MyShapeCollection<T extends Shape>{
    List<T> shapes;
    public double getAreaSum(){
        double areaSum = 0;
        for(Shape s : shapes){
            areaSum += s.getArea();
        }
        return areaSum;
    }
}

public static void main(String[] args){
    MyShapeCollection<Rectangle> rectangles = new MyShapeCollection<Rectangle>();

    //bad code monkey. String does not implement Shape!
    //this line won't compile. including it for demonstration purposes.
    MyShapeCollection<String> willNotCompile = new MyShapeCollection<String>();
}

如果您的收藏只包含字符串,则不需要泛型。

答案 1 :(得分:2)

是的,您的理解是正确的。

然后,在此添加特定于类型的代码会破坏泛型的目的。

更好的解决方案如下。

<强> Client.java

public class Client {

    public static void main(String[] args) {
        // String container
        Container<String> stringContainer = new StringContainer();
        stringContainer.setItem("Test");
        //stringContainer.setItem(new StringBuffer("")); // compilation error, type safety checking 

        System.out.println(stringContainer.getItem().toUpperCase()); // No need to cast

    }

}

<强> Container.java

class Container<T> {

    private T item;

    public T getItem(){
        return item;
    }

    public void setItem(T item){

        this.item = item;
    }
}

<强> StringContainer.java

class StringContainer extends Container<String> {

    @Override   
    public void setItem(String item){           
        System.out.println( item.toUpperCase() ); 
        super.setItem( item );
    }
}

答案 2 :(得分:1)

是的,或者您可以为不同类型的参数重载setItem()方法,但实际上情况更糟。

答案 3 :(得分:1)

是的,对于您的案例,必须进行投射。因为你专门使用字符串函数。

但它就像你没有使用通用功能一样。

如果你想打印项目,那么你可以覆盖每个项目的toString()方法,并且可以直接将项目对象放在sysout()中。通过这样做,将不需要任何转换,并且所有代码都是通用的。

你在这说什么