`

教你怎么绕过泛型检查

    博客分类:
  • Java
阅读更多
  看看下面这个java小程序:

public class Test { 
public static void append(List list){ 
list.add("asdf"); 
} 

public static void main(String[] args) { 
List<Integer> intList = new ArrayList<Integer>(); 
append(intList); 
System.out.println(intList.get(0)); 
} 
}

//运行结果:asdf


  可能会java的朋友们有的会认为这个程序有错误。不好意思,这个程序真的没错……

  这涉及到JDK1.5的“新”特性——泛型。

  我们可以看到,intList使用了泛型,其中的元素应该是Integer类型的,但是上例程序中却成功的将一个String类型存入了其中,更重要的是这个String字符串根本不能转换为Integer类型。

  好吧,我们不得不承认,我们成功的“穿墙”了——绕过了泛型检查。

  那么,我们是怎么做到的呢?

  正如你所见,虽然我们声明了一个List<Integer>类型的链表,但是,当我们把这个链表当参数传给Test类的append方法时,我们看到append方法的形参是不带泛型的。也就是说,理论上我们可以在这个传入的链表中加入任何类型的元素。

  好吧,最后我们就把一个字符串加入到了intList中去了……

  是不是很神奇啊?

  其实不然,我们只是简单的绕过了泛型的检查而已。我说绕过了检查,那么,是谁检查的呢?

  你猜对了,就是编译器!!!

  编译器干了什么?

  问得好!我们要知道的是,java中的泛型基本上完全是在编译器中实现的(话怎么这么绕呢),由编译器执行类型检查和类型推断,然后生成普通的无泛型的字节码。这种实现技术我们称其为擦除(erasure)。

  那么好了,我们更清晰的知道在上例中我们干了什么了——我们成功“忽悠”了编译器。(心里很爽啊,原来编译器也2啊)

  那么这下好了,编译器绕过了,那么你认为接下来我们是不是可以为所欲为了呢?

  呵呵,你看到了,我们已经“犯罪”了,可是JVM居然还呆呆的运行着,明明intList里只能有Integer的元素,现在可好,居然把"asdf"都打印出来了。呵呵………………

  为所欲为?你真以为你是神啊?

  你在打印语句中打印这个东东试试:

  intList.get(0).getClass()

  怎么样,傻了吧?

  发生了什么事?想知道?

  可是,我现在只是在说怎么绕过泛型检查,好了,老实说,我已经说完了!!

  你还想知道什么呢?这跟我有什么关系?

  等我下次心情好的时候再跟我说吧,或许我会说点什么的!!

  呵呵…………………………………………………………………………………………………………
分享到:
评论

相关推荐

    java教程ppt,讲述了java reflect.,对大家应该很有帮助

    同时,反射可以绕过访问控制,可能导致安全问题,因此在使用时应谨慎。 9. **实际应用**:Java反射广泛应用于插件系统、框架设计(如Spring框架)、测试工具(如JUnit)以及动态代理等领域。 本Java反射教程的PPT...

    java reflection in action

    通过`setAccessible(true)`可以暂时绕过访问控制检查。 7. **动态代理**:Java反射API中的`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口可以实现动态代理,允许在运行时创建代理类,...

    fanshe_JAVA.zip_java 反射

    使用反射虽然提供了强大的灵活性,但也可能引入安全风险和性能开销,因为反射操作通常比常规操作慢,并且可以绕过一些安全控制。 10. **应用场景**: 反射常用于框架开发(如Spring框架),动态代理(如JDK动态...

    Javafanshe.rar_java 反射_java反射_反射_反射机制

    通过`Class.newInstance()`或`Constructor.newInstance()`方法,我们可以绕过常规的构造器调用。 4. **方法的调用**:反射可以调用类的私有方法、静态方法或实例方法,通过`Method`对象的`invoke()`方法实现。 5. ...

    JavaReflectionTuto:Java Reflection API入门教程

    - **安全风险**:反射可以绕过访问控制,可能引发安全问题,因此应谨慎使用。 - **异常处理**:反射操作容易抛出异常,如`ClassNotFoundException`、`IllegalAccessException`等,编写代码时需充分捕获。 - **...

    rustprimer-1.0.5.pdf

    Unsafe Rust用于与外部代码和硬件交互,它绕过了Rust的安全检查,因此需要谨慎使用。 标准库为Rust提供了大量的实用工具和数据结构,包括系统命令调用、目录操作和网络模块等。文档还展示了如何使用这些工具,例如...

Global site tag (gtag.js) - Google Analytics