面试了一个地方做银行支付系统的,对方的技术人员最后问我“能不能加载一个自己重写的java.lang.String”。我想到的第一个回答是“有什么可能需要重写java.lang.String”,想了想还是没说。
不可能啊,类加载器的安全模型不同意。
加载是可以的,只需要自己重写一个classloader,但是被系统应用又是另外的事情了,看看下面的程序。我说这些的目的不是在讨论写一个自己的Integer或者String,其实是思考角度的问题。
站在应用Java做业务过程角度上其实不需要过分的关注Java是怎么实现安全管理的,因为在应用中根本就不应该考虑这种替换核心类的实现方式。
public class SimpleClassLoader extends ClassLoader { private Hashtable classes = new Hashtable();
public SimpleClassLoader() { }
/**
- This sample function for reading class implementations reads
- them from the local file system
/*
- If we caught an exception, either the class wasnt found or it
- was unreadable by our process.
/**
- This is a simple version for external clients since they
- will always want the class resolved before it is returned
- to them.
/**
- This is the required version of loadClass which is called
- both from loadClass above and from the internal function
- FindClassFromClass.
System.out.println(" >>>>>> Load class : "+className);
/* Check our local cache of classes */ result = (Class)classes.get(className); if (result != null) { System.out.println(" >>>>>> returning cached result."); return result; }
/* Check with the primordial class loader */ try { if(!className.equalsIgnoreCase("java/lang/Integer")) { result = super.findSystemClass(className); System.out.println(" >>>>>> returning system class (in CLASSPATH)."); return result; } } catch (ClassNotFoundException e) { System.out.println(" >>>>>> Not a system class."); }
/* Try to load it from our repository */ classData = getClassImplFromDataBase(className); if (classData == null) { throw new ClassNotFoundException(); }
/* Define it (parse the class file) */ result = defineClass(classData, 0, classData.length); if (result == null) { throw new ClassFormatError(); }
if (resolveIt) { resolveClass(result); }
classes.put(className, result); System.out.println(" >>>>>> Returning newly loaded class."); return result; } ============================================================================= package java.lang;
public class Integer { public String toString() { return "mine"; } } =============================================================================== public class TestClass{ public static void main(String[] args) throws Exception { SimpleClassLoader sc = new SimpleClassLoader(); Object o; o = (sc.loadClass("java/lang/Integer")).newInstance(); o.toString(); } }
呵呵,LS的classLoader可以说不是一个完整的classLoader,真的classLoader是有委托模型的,是要指定父子关系,只要指定了父子关系,那么就不可能通过自己写的classLoader来加载与类库同名的类了,因为加载顺序是先父加载器后子加载器。
没错的,这个方式下class被加载起来了,但是还不可能被真正的用起来,我这么写一个也仅仅是为了娱乐。
我发这个帖子也不是为了讨论技术,算是放水发个牢骚吧,这不是杂类么。
不需要重写一个ClassLoader吧?直接用URLClassloader指定路径,将String放在指定路径下不可以么?
很多年轻人对面试题耿耿于怀。 其实,面试出题,和考试出题,完全是两码事。 后者,你答对了,就给分,答错了,没分。 面试题,仅仅是一个话题。面试人随便找个话题,与你随便漫谈,从中了解你对技术的感悟程度。
ls说的是,面试更多的是互相了解的过程。 应该是思考方式不同吧,我遇到的面试人员几乎都是专注于某个技术细节的深入考察。但是我做过的项目都没有需要那么多对于某一个细节的太深入计较,反而更多的是对于应用过程的理解和程序结构上的考虑,很多细节在遇到的时候即时去学习就可以了。
也许我本来没想过做技术专家吧,呵呵。
很多年轻人对面试题耿耿于怀。 其实,面试出题,和考试出题,完全是两码事。 后者,你答对了,就给分,答错了,没分。 面试题,仅仅是一个话题。面试人随便找个话题,与你随便漫谈,从中了解你对技术的感悟程度。 ------------------------------------ 面试的时候,出任何题目的目的都是为了了解应聘者,更多是从其回答交流看这个人对技术理解的程度。像我们公司技术面试出题什么都有,但并不是要求应聘者答出标准答案,而是希望应聘者通过题目展开话题,最好是能延伸到其他方面,更好展现自己好让公司更好了解应聘者。 [该贴被BinnyJ于2009-11-02 18:26修改过]