java泛型语法如何帮助避免类型转换? [英] How does java generics syntax help avoid type casting?

查看:47
本文介绍了java泛型语法如何帮助避免类型转换?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是代码,

import java.util.List;
import java.util.ArrayList;


public class Dummy {
    public static void main(String[] args) {
        List<String> lst = new  ArrayList<String>();
        lst.add("a string");
        lst.add("another string");
        String s = lst.get(0);
    } //end main
}

当构造函数new ArrayList();被调用时,Object类型的数组被创建.

when the constructor new ArrayList<String>(); is invoked, array of type Object is created.

..

lst 保存 Object[0] 数组.

所以,如果 Object 类型的数组是由构造函数创建的,javac 如何在此语句中看不到类型转换问题 String s = lst.get(0);,尽管在​​调用构造函数时使用了通用语法?

So, If array of type Object gets created by constructor, How does javac does not see type casting issue in this statement String s = lst.get(0);, despite generic syntax is used while invoking constructor?

推荐答案

这里是一些非通用代码:

Here is some non-generic code:

public class MyList {

    List myData = new ArrayList();

    public void add(Object ob) {
        myData.add(ob);
    }

    public Object getAtIndex(int ix) {
        return myData.get(ix);
    }
}

此代码将允许您将任何类型的对象存储到您的 MyList 实例中即使 MyList 的约定指定对象必须全部为相同类型.此外,如果您使用 MyList 实例来存储 String 实例,则在检索它们时必须手动将它们转换为 String.

This code will allow you to store an object of any type into your MyList instances even if the contract of MyList specifies that the objects must all be of the same type. Moreover if you use a MyList instance to store String instances, you must manually cast them to String when you retrieve them.

String myString = (String) myList.get(1);

上面的 MyList 类不是类型安全的.如果将 String 实例以外的对象存储到您的 MyList 实例中(这可能在运行时发生而没有任何抱怨),则上述赋值语句很可能会失败并出现 ClassCastException.

The above MyList class is not type safe. It is most definitely possible that the above assignment statement will fail with a ClassCastException if an object other than a String instance was stored into your MyList instance (which can happen at run-time without any complaint).

这是一个泛化的 MyList 类:

Here is a generified MyList class:

public class MyList<T> {

    List<T> myData = new ArrayList<>();

    public void add(T ob) {
        myData.add(ob);
    }

    public T getAtIndex(int ix) {
        return myData.get(ix);
    }
}

现在,编译器保证只能从 MyList 实例中添加和检索 T 实例.因为编译器保证总是返回 T 实例,你可以使用这样的语法而无需任何手动转换:

Now, the compiler guarantees that only T instances can be added and retrieved from MyList instances. Because the compiler guarantees that T instances will always be returned, you can use syntax like this without any manual casting:

String myString = myList.get(1);

泛型的 MyList 类现在是类型安全的.编译器不允许您将除 T 实例以外的任何内容存储到 MyList 实例中,这保证在运行时不会发生 ClassCastExceptions.如果您检查字节码,您会发现编译器已自动进行了强制转换.

The generified MyList class is now type-safe. The compiler won't allow you to store anything but T instances into your MyList instances, which guarantees that no ClassCastExceptions will occur at run-time. If you examine the byte-code, you'll find that the compiler has placed a cast automatically.

Java 中的泛型是一种仅在编译时的现象.在字节码中,上述 MyList 类中对 T 的所有引用都被替换为 Object.这个过程被称为类型擦除".请务必记住,Java 中的类型安全仅由编译器提供.如果你的程序编译没有任何错误AND没有任何警告,那么你的程序,泛型和所有,都是类型安全的.然而,编译后的程序几乎没有保留关于泛型参数的信息.

Generics in Java are a compile-time only phenomenon. In the byte-code, all references to T in the MyList class above are replaced by Object. This process is referred to as "type erasure". It is important to remember that type safety in Java is provided by the compiler only. If your program compiles without any errors AND without any warnings, then your program, generics and all, is type safe. The compiled program, however, has retained almost no information about the generic parameters.

这篇关于java泛型语法如何帮助避免类型转换?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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