import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class Test {
public class MyLoader extends ClassLoader {
private final String path = getClass().getResource("/").getPath();
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
byte[] b = getData(name);
return defineClass(name, b, 0, b.length);
}
private byte[] getData(String url) {
byte[] b = null;
try (FileInputStream reader = new FileInputStream(new StringBuffer(
path).append(url.replace('.', File.separatorChar))
.append(".class").toString())) {
b = new byte[reader.available()];
reader.read(b, 0, b.length);
} catch (IOException e) {
e.printStackTrace();
}
return b;
}
}
public static void main(String[] args) throws Exception {
new Test().foo();
}
private void foo() throws Exception {
Class<?> cls = Foo.class;
/* 使用MyLoader加载非public类 */
// cls = new MyLoader().findClass(Foo.class.getName());
Object obj = cls.newInstance();// java.lang.IllegalAccessException异常
cls.getDeclaredMethod("bar").invoke(obj);
}
}
/*public*/ class Foo {
public void bar() {
System.out.println("asdfghjkl");
}
}
刚了解ClassLoader和反射,遇到此问题,望高手指教。
------解决方案--------------------
自定义类加载的机制中反射获取类对象时会有安全机制的限制,所以只能用public。如果想深入研究应该多读点jdk源码,这样子可能了解的多了,就更容易理解了。
------解决方案--------------------
public T newInstance()
throws InstantiationException, IllegalAccessException
{
if (System.getSecurityManager() != null) {
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
}
return newInstance0();
}
------解决方案--------------------
还是版主威武,直接上源码,呵呵,省得解释那么多了。。。
------解决方案--------------------
对头,就是反射的限制,加载器没限制,加载还是可以正常加载的,但是获取实例的时候有私有成员安全验证。所以问题不在加载而在反射。。。