1.JVM如何加载class文件
JVM屏蔽了与具体操作系统平台相关的信息,使得只需生成在java虚拟机上能够运行的目标代码,即字节码,就可以在多种平台上无需修改的执行。
2.什么是反射
反射机制:java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法 ,对于任意一个对象,都能够调用它的任意方法和属性;的动态获取信息以及动态调用对象方法的机制。
public class Robot {
private String name;
static{
System.out.println("Hello,I am a robot!!!");
}
private String throwHello(String name){
return "Hello"+name;
}
public void sayHi(String name){
System.out.println("Welcome "+name);
}
}
public class ReflectSample {
public static void main(String[] args) throws Exception{
//1.根据类的包路径名获取类
Class rc = Class.forName("jvm.reflect.Robot");
//2.实例化该类对象
Robot robot = (Robot)rc.newInstance();
System.out.println("Class name is "+rc.getName());
//3.根据方法名和参数类型获取方法
//getDeclaredMethod可以获得除继承方法和抽象方法外的所有方法
Method throwHello = rc.getDeclaredMethod("throwHello", String.class);
throwHello.setAccessible(true);
//4.invoke指定对象和参数调用方法
Object content = throwHello.invoke(robot, "Bob");
System.out.println("throwHello return is:"+content);
//getMethod可以继承方法+抽象方法+public方法
Method sayHi = rc.getMethod("sayHi",String.class);
sayHi.invoke(robot, "Alice");
//设置私有属性为可访问
Field name = rc.getDeclaredField("name");
name.setAccessible(true);
name.set(robot,"PeakGe");
}
}
3.谈谈ClassLoader
- ClassLoader的主要作用是从系统外部获得Class二进制数据流。
- ClassLoader负责通过将Class文件里的二进制数据流装载进系统,然后交给java虚拟机进行连接、初始化等操作
- 自定义的ClassLoader:继承ClassLoader,重写findClass方法
public class MyClassLoader extends ClassLoader{
public String path;
public String classLoaderName;
//用于寻找类文件,读取字节数组,传给defineClass
@Override
protected Class findClass(String name) throws ClassNotFoundException {
byte[] buff=loadClassData(name);
return defineClass(name,buff,0,buff.length);
}
//用于加载类文件
private byte[] loadClassData(String name){
String filepath = path + name+".class";
InputStream in=null;
ByteArrayOutputStream out=null;
try {
in=new FileInputStream(new File(filepath));
out=new ByteArrayOutputStream();
int i=0;
while((i=in.read())!=-1){
out.write(i);
}
}catch (Exception e){
e.printStackTrace();
}finally {
try{
in.close();
out.close();
}catch (Exception e){
e.printStackTrace();
}
}
return out.toByteArray();
}
}
4.ClassLoader的双亲委派机制
5.loadClass和forName的区别
- Class.forName得到的class是已经了完成了整个装载过程的
- Classloader.loadClass得到的class是只完成了加载阶段的