我知道我们可以通过在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/
答案 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()中。通过这样做,将不需要任何转换,并且所有代码都是通用的。
你在这说什么