深入理解ClassLoader 是什么? 相信大家在准备面试的时候都会背过Java的类加载机制,双亲委派模型。
就是当JVM收到一个类加载请求的时候,当前的类加载器首先会将类加载器传递给它的父类,父类尝试加载,如果失败继续向上传递,如果所有的父类都无法加载,则当前类加载器自己处理。
那这段话理解起来还是比较容易的,但是具体是如何做的呢?下面进行分析。
为什么? 那为什么要使用双亲委派模型吗?当前类加载器自己处理不行吗?
如果我们自己写了一个java.lang.Object类的话,那当前的类加载器直接选择加载的话,那加载的类中就会有两个一样的Object类。应用程序将会变的非常混乱。
怎么做? 下面从源码开始看Java是如何进行类加载的。
ClassLoader 介绍 先进入ClassLoader类中public abstract class ClassLoader, 可以先看一下doc,介绍了ClassLoader这个类,
A class loader is an object that is responsible for loading classes. The class ClassLoader is an abstract class. Given the binary name of a class, a class loader should attempt to locate or generate data that constitutes a definition for the class. A typical strategy is to transform the name into a file name and then read a “class file” of that name from a file system.
...
Effective Java Reading Notes - 1 最近感觉自己对于Java越来越陌生了,遂看EffectiveJava来温习一下。这本书就是一个清单,分为90个item。
Introduction 简介里面就简单说明了一下本书的重点,重点不在于如何写出高性能的Java代码,而是写出clear,correct,usable,robust,flexible,maintainable的代码。
Creating and Destroying Objects Item 1: Consider static factory methods instead of constructors 获取一个类的实例的传统方式是提供构造方法。另外一种方式是创建静态工厂方法,这里的工厂并不是设计模式中的工厂。之前有个同事喜欢使用静态工厂方法来创建类(Luzihao5),具体看到他的代码就可以知道。
1 2 3 4 // 书中的样例使用了基本类型转换包装类的例子 public static Boolean valueOf(boolean b) { return b ? Boolean.TRUE : Boolean.FALSE; } 下面列举一下静态工厂方法获取类实例的优点和缺点:
advantages: 自定义方法名称:构造方法只能是类名称,而静态工厂方法可以取具体含义的名称。这点确实,如果有多个构造函数的话,往往需要去找到底使用哪个构造函数来创建实例。 不需要每次都创建一个新的对象:如上面的例子,每次只需要返回定义好的常量即可。 静态方法返回的类型可以是定义返回类型的子类 Item 6: Avoid creating unnecessary objects 如题名,避免创建不必要的对象。
以String作为例子: 1 2 String s = new String("bikini"); // 创建一个新的实例 String s = "bikini"; // 从String池创建 以后无论创建多少个 bikini 都会指向第一次创建的地址 以正则表达式的匹配为例: 1 2 3 4 5 6 7 8 9 10 11 12 // Performance can be greatly inproved static boolean isRomanNumberal(String s) { return s.matches("^(?=.)") } // Reusing expensive object for improved performence public class RomanNumberals { private static final Pattern ROMAN = Pattern.compile("^(?=.)"); static boolean isRomanNumeral(String s) { return ROMAN.matchers(s).matches(); } } 使用基础类型而不是包装类