张老师的视频中,做一个测试web项目,正常是得到类加载器(子-->父)为
org.apache.catalina.loader.WebappClassLoader
org.apache.catalina.loader.StandardClassLoader
sun.misc.Launcher$AppClassLoader
sun.misc.Launcher$ExtClassLoader
自己的类打成Jar输出到ext目录(JDK主目录jre\lib\ext),会出现找不到HttpServlet的错误,把servlet-api.jar放到ext目录则正常。重新启动Tomcat,得到sun.misc.Launcher$ExtClassLoader。这是因为Tomcat自定义了类加载器。
我们已经知道,[font="][size=10.5pt]Java[/size][/font][font=宋体][size=10.5pt]中类的加载是父加载器委托机制,为啥要这样?
[/size][/font][font=宋体][size=10.5pt]我们知道[/size][/font][font="][size=10.5pt]java[/size][/font][font=宋体][size=10.5pt]中有四种访问级别,其中[/size][/font][font="][size=10.5pt]protected[/size][/font][font=宋体][size=10.5pt]是包内和子类可见,默认级别是包内可见。如果我们定义一个类[/size][/font][font="][size=10.5pt]java.lang.MyClass,[/size][/font][font=宋体][size=10.5pt]那么在[/size][/font][font="][size=10.5pt]MyClass[/size][/font][font=宋体][size=10.5pt]中能访问[/size][/font][font="][size=10.5pt]java.lang.*[/size][/font][font=宋体][size=10.5pt]核心库的默认级别成员吗吗?如果可以,那么就会出问题,知道核心甚至修改细节。实际上不可能访问的,因为[/size][/font][font="][size=10.5pt]java.lang.MyClass[/size][/font][font=宋体][size=10.5pt]与系统核心库的类加载器不同,所以是无法访问的,这样更安全。[/size][/font]
类似的一个问题是,为啥创建子类对象时要先调用父类的构造方法?因为需要先初始化直接或间接被子类继承的变量(想一想构造方法是做什么的)。 |