前言
就比如我前几天被面试官问什么是反射???
而我的回答是!!!
反射是动态语言的关键,反射允许程序在执行期间借助Reflection API取得任何类的内部信息,并能直接操作任曦对象的内部属性及方法。
1.Java反射提供的功能
- 在运行时判断任意一个对象所属的类
- 在运行时构造任意一个类的对象
- 在运行时判断任意一个类具有的成员变量和方法
- 在运行时调用任意一个对象的成员变量和方法
2.放射常用的API
java.lang.Class : 代表一个类java.lang.reflect.Method :代表类的方法java.lang.reflect.Field :代表类的成员变量java .lang.reflect.Construct :代表类的构造方法
3.java.lang.Class
我们创建一个类,通过编译(Javac.exe ),生成对应的.class文件。之后我们使用java.exe 加载(JVM类加载器)此.class文件。此.class文件加载到内存以后,就是一个运行时类。存放在缓冲区,Class允许通过一个实例化对象找到一个类的完成信息资料。
Class类的作用:
- 1.每一个运行时类只加载一次!
- 2.获取对应的运行时类的完整结构(属性,方法,构造器,内部类,父类,所在包,异常,注 解。。。。) ?
- 3.调用对应的运行时类的指定结构(属性,方法,构造器)
- 4.反射应用:动态代理
4.获取Class对象。
1.调用运行时类本身的.class属性
Class<Person> personClass01 = Person.class;
2.通过运行时类的一个对象
Person person = new Person();
Class<? extends Person> aClass = person.getClass();
3.通过Class.forName("com.jdy.bean.Dog")
Class<?> aClass1 = Class.forName("com.jdy.bean.Dog");
4.通过类的加载器
ClassLoader classLoader = this.getClass().getClassLoader();
5.Class类的常用方法
public Constructor<?>[] getConstructors() throws SecurityException
public Field[] getDeclaredFields() throws SecurityException
public Field[] getFields() throws SecurityException
public Method[] getMethods() throws SecurityException
public Class<?>[] getInterfaces()
public native Class<? super T> getSuperclass();
6.Class应用
(1)通过无参构造实例化对象
String packageName ="com.jdy.bean.Dog";
Class<?> aClass = Class.forName(packageName);
Dog dog = (Dog)aClass.newInstance();
(2)调用有参构造器实例化对象
public int getModifiers()
public String getName()
public Class<?>[] getParameterTypes()
public T newInstance(Object ... initargs)
<Dog> constructor = (Constructor<Dog>) aClass.getConstructor(String.class, String.class, String.class);
Dog dog1 = constructor.newInstance("二狗子", "黑背", "8");
(3)获取类结构
Constructor :表示类的构造器Field :表示类的属性Method :表示类的方法
取得所有实现的接口
[] interfaces = aClass.getInterfaces();
取得父类
Class<?> superclass = aClass.getSuperclass();
取得全部构造器
Constructor<?>[] constructors = aClass.getConstructors();
将访问修饰符由数字转化成可看懂的
int modifiers = declaredField.getModifiers();
System.out.println("modifiers = " + Modifier.toString(modifiers));
取得所有的方法
Method[] methods = aClass.getMethods();
取得全部属性
Field[] fields = aClass.getFields();
Field[] declaredFields = aClass.getDeclaredFields();
Field的常用方法
public Object get(Object obj)throws IllegalArgumentException, IllegalAccessException
public void set(Object obj, Object value) throws IllegalArgumentException, IllegalAccessException
public int getModifiers()
public String getName()
public boolean isAccessible()
public void setAccessible(boolean flag) throws SecurityException
(4)通过反射待用类中的方法
Method destory_method = aClass.getMethod("destory_method");
Object invoke = destory_method.invoke(aClass.newInstance());
(5)通过方法操作属性
反射中通过Field类提供的set()/get() 完成设置和取得属性内容的操作,但是类中的属性都设置成私有的访问权限,所以在使用set()/get() 方法时首先要使用Field() 中的setAccessible(true) ,方法将需要操作的属性设置成可被外部访问。
Field field0 = personClass.getDeclaredField("address");
field0.setAccessible(true);
field0.set(person,"xian");
System.out.println(person);
一般给类的属性赋值,不建议使用以上方法,因为扩大了属性的访问权限,建议使用类中属性的getter/setter方法
5.ClassLoader:类的加载器 类的加载器是用来把类(class )装载进内存的,JVM规范定义了两种类型的类加载器: 启动类加载器(bootstrap ) 用户类加载器(user-defind class loader ) JVM 在运行时会产生3个类加载器组成的初始化加载器层次结构
Bootstrap ClassLoader:引导类加载器:用C++ 编写,时jVM 自带的类加载器,负责JAVA平台核心类库的加载。该加载器无法直接获取资料
>
ClassLoader parent1 = parent.getParent();
System.out.println("引导类加载器 = " + parent1);
Extension ClassLoader:负责jre/lib/ext目录下的jar包或者 -D java.ext.dirs指定目录下的jar包装入工作库
ClassLoader parent = loader.getParent();
System.out.println("扩展类加载器 = " + parent);
System ClassLoader:系统类加载器,负责java -classpath 或者 -D java.class.path 所知的目录下的类与jar包装入工作,是最常用的加载器
ClassLoader loader = ClassLoader.getSystemClassLoader();
System.out.println("系统类加载器 = " + loader);
获取某个实例的类加载器
Person person = new Person();
Class<? extends Person> aClass = person.getClass();
ClassLoader classLoader = aClass.getClassLoader();
System.out.println("Perosn类的加载器 = " +classLoader);
aClass1 = Class.forName("com.jdy.bean.Dog");
ClassLoader classLoader1 = aClass1.getClassLoader();
System.out.println("Dog类的加载器 = " + classLoader1);
类加载器配合IO
ClassLoader classLoader2 = this.getClass().getClassLoader();
InputStream resourceAsStream = classLoader2.getResourceAsStream("test.properties");
Properties properties = new Properties();
properties.load(resourceAsStream);
最新2021整理收集的一些高频面试题(都整理成文档),有很多干货,包含mysql,netty,spring,线程,spring cloud、jvm、源码、算法等详细讲解,也有详细的学习规划图,面试题整理等,需要获取这些内容的朋友请加Q君样:593142328
|