Java反射机制的大厂面试题
反射机制概念
Java 反射机制在程序运行时,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性。这种 动态的获取信息 以及 动态调用对象的方法 的功能称为 java 的反射机制。
为什么引入反射概念
相信你看上面的概念,心中没有泛起任何的波澜,动态的获取信息、动态调用对象方法黑人问号。下面一段简单代码作为i出发点,从java虚拟机角度阐述
- 写下如下代码
public class Main{
public static int number = 1;
public static void main(String args[]) {
System.out.println("hello World");
}
}
- 调用
javac Main.java
命令将Main.java
文件编译成Main.class
文件 - 之后执行
java Main
命令后,java虚拟机启动,进行类加载过程,方法区中存储类的静态存储结构,同时在内存中生成一个代表该类的java.lang.Class对象,作为方法区中该类的各种数据的访问入口
上述过程表明,编译阶段,就已经明确java虚拟机要加载的类(Main类),如果你的程序运行中,突然需要加载远程服务器的类(运行中加载),这时候反射机制就粉墨登场
有一个很经典的场景就是加载数据库驱动类,只有运行的时候通过参数,才能确定是加载com.java.dbtest.myqlConnection
(mysql驱动类),还是加载com.java.dbtest.oracleConnection
此时只需要简单调用Class.forName(com.java.dbtest.myqlConnection)
即可动态得完成加载类的过程。
利用反射机制对类进行两次加载
import java.io.IOException;
import java.io.InputStream;
public class Main{
public static void main(String args[]) throws Exception{
//自定义类加载器
ClassLoader myLoader = new ClassLoader() {
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException{
try{
String fileName = name.substring(name.lastIndexOf(".") + 1) + ".class";
InputStream is = getClass().getResourceAsStream(fileName);
if(is == null) {
return super.loadClass(name);
}
byte[] b = new byte[is.available()];
is.read(b);
return defineClass(name, b, 0, b.length);
}catch(IOException e) {
throw new ClassNotFoundException(name);
}
}
};
//使用反射机制加载并实例化
Object obj = myLoader.loadClass("Main").newInstance();
System.out.print(obj instanceof Main);
}
}
//结果为false