Reflection
ClassLoader的类加载机制
并非一次性加载。
需要的时候加载(运行期间动态加载)。
java-verbose:class可以观察类的具体加载过程。
static语句块在加载后执行一次。
dynamic语句块每次new新的对象都会执行,等同于构造方法中语句,用得也比较少。
首先bootstrap class loader把其他的Class loader给load进来,然后不同的class loader去load不同的class。
public class TestClassLoader {
public static void main(String[] args) {
ClassLoader cl = TestClassLoader.class.getClassLoader();
while (cl != null) {
System.out.println(cl.getClass().getName());
cl = cl.getParent();
}
}
}
这里解释一下getParent这个方法不是得到父类,因为他们之间没有继承关系,只是得到加载的顺序,是层次关系。
classloader在load class的时候首先找上一层loader是不是load过了,如果已经load过了就不会再load了,安全性非常好。这样自己写的String.class永远没有机会执行。
package yn;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Reflection {
/**
* @param args
* @throws ClassNotFoundException
* @throws IllegalAccessException
* @throws InstantiationException
* @throws InvocationTargetException
* @throws IllegalArgumentException
*/
public static void main(String[] args) throws ClassNotFoundException,
InstantiationException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException {
String str = "yn.T";
Class c = Class.forName(str);
Object o = c.newInstance();
Method[] methods = c.getMethods();
for (Method m : methods) {
if (m.getName().equals("m")) {
m.invoke(o, 1, 2); // 参数是变长的
Class returnType = m.getReturnType();
System.out.println(returnType);
for (Class paramType : m.getParameterTypes()) {
System.out.println(paramType.getName());
}
}
}
}
}
class T {
static {
System.out.println("T loaded..");
}
T() {
System.out.println("T constructed..");
}
public void mm() {
System.out.println("mm invoke..");
}
public int m(int a, int b) {
System.out.println(a + b);
return a + b;
}
}