难题求解
今天和同事讨论一道面试题:“是否有办法禁用String的equals方法?”
有两个一下子就能想到的办法:
1,修改源码重新打包。
2,利用类加载器加载一个虚假的类。(此方法如果我没记错的话,应该是不可行的,java虚拟机上有详细介绍)
然后如果不用这两种办法,而是在代码级别是否可以解决呢?
我首先想到的就是是否可以利用String类在JVM中的class对象来解决,其实也就是反射机制。我在Method类里找到了一个setAccessible方法,尝试了下:
String test = "hello world!";Method[] methods = String.class.getMethods();for(Method method : methods) {if(method.getName().equals("equals")) {System.out.println(method.isAccessible());method.setAccessible(false);}}System.out.println(test.equals("hello world!"));结果证明这个方法是不可行的,我查找了些资料,setAccessible其实是设置当JVM做反射时是否做安全检查,而不是该方法是否能够被访问。
我就此郁闷了,想不出还有什么方向可以考虑的。
求帮助。 1 楼 aspnetdb 2011-03-01 关注一下,确实挺难。String是final修饰的,不能继承和所以没法覆盖。
我感觉是不是题意理解错了? 2 楼 mabusyao 2011-03-02 呵呵,继承这条路我也考虑过了,java继承因为要遵循替换原则,所以子类没有办法降低父类的方法访问权限。方法覆盖的话,已有的代码需要重写,也会产生问题。 3 楼 mabusyao 2011-04-20 最近几天研究了下java中的线程上下文classloader, 据说是可以跳过所谓的父类委托机制。
事实证明确实是可以用自己写的classloader来设置线程上下文classloader,然而当真正进行加载的时候, 却报了一个“Prohibited package name: java.lang”的错。
也就是说JVM在设计的时候就把这些包给设定死了,不允许用这种方式加载。
当然,对于JNDI的加载,线程上下文classloader还是非常有用的。
看来加载机制这里是没什么搞头了。。。