本帖最后由 小鲁哥哥 于 2017-8-24 16:51 编辑
小鲁哥哥白话笔记-反射
今天给大家讲一讲反射的概念,反射虽然在我们工作中用到的地方不是很多,但是我们所有的框架基本都会用到反射技术去实现相应的功能,学好反射技术有利于我们以后阅读框架源码,更好的理解别人的一个思想和逻辑。从而使我们更加得心应手的去做开发的工作。 什么是反射: JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法。大家能发现这里边比较核心的一句话就是,对于任意一个类,都能获取到这个类的所有属性和方法,没错,你没有看错,是所有的属性和方法。不管这个属性或者方法是private还是public以及其他修饰符修饰的,都能获取到,这就是反射的强大之处。 反射技术是如何工作的? 我们都知道,java文件经过编译,会生成class字节码文件,反射就是通过class字节码文件获取它里边的所有内容。 对于获取class字节码文件,我们有三种方式: 1.对象名.getCalss(); // 次方法来自于Object 对象已经存在的情况下, 可以使用这种方式 2.类名.class // 类名.class这是一个静态的属性, 只要知道类名, 就可以获取 3.Class.forName(“com.itheima_01.Student”); // 通过Class类中的静态方法, 指定字符串, 该字符串是类的全类名(包名+类名) // 此处将会抛出异常都系ClassNotFoundException 防止传入错误的类名 举个例子: [Java] 纯文本查看 复制代码 package com.itheima_01;
/*
* 反射:
* 在运行时,我们可以获取任意一个类的所有方法和属性
* 在运行时,让我们调用任意一个对象的所有方法和属性
*
* 反射的前提:
* 要获取类的对象(Class对象)
*
*/
public class ReflectDemo {
public static void main(String[] args) throws ClassNotFoundException {
// 通过Object的getClass()方法获取,必须要有对象
Student s = new Student();
Class clazz = s.getClass();
// 通过类名获取字节码对象
Class clazz2 = Student.class;
// static Class<?> forName(String className)
Class clazz3 = Class.forName("com.itheima_01.Student");
System.out.println(clazz == clazz2);//打印字节码文件
System.out.println(clazz == clazz3);
System.out.println(clazz);
}
} 我们获取到了字节码文件,下一步我们就是通过字节码文件获取这个对象的所有东西。例如创建对象,属性,方法等。 我们先了解如何通过构造函数创建对象: 步骤: 1.获得Class对象 2获得构造 3.通过构造对象获得实例化对象 举个例子: [Java] 纯文本查看 复制代码 package com.itheima_01;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
/*
* 通过反射获取构造方法并使用
* Constructor<?>[] getConstructors()
* Constructor<T> getConstructor(Class<?>... parameterTypes)
* T newInstance()
*
*Constructor:
* T newInstance(Object... initargs)
*/
public class ReflectDemo2 {
public static void main(String[] args) throws ReflectiveOperationException {
//获取字节码文件
Class clazz = Class.forName("com.itheima_01.Student");
//method(clazz);
//Constructor<T> getConstructor(Class<?>... parameterTypes)
//method2(clazz);
//method3(clazz);
//通过字节码文件获取对象
Object obj = clazz.newInstance();
System.out.println(obj);
}
private static void method3(Class clazz)
throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
Constructor c = clazz.getConstructor(String.class,int.class);//获取有参构造,参数1类型为String,参数2类型为int
System.out.println(c);
Object obj = c.newInstance("lisi",30);
System.out.println(obj);
}
private static void method2(Class clazz)
throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
Constructor c = clazz.getConstructor();//获取无参构造
System.out.println(c);
Object obj = c.newInstance();
System.out.println(obj);
}
private static void method(Class clazz) {
//Constructor<?>[] getConstructors() :获取所有public修饰的构造方法
Constructor[] cs = clazz.getConstructors();
for (int i = 0; i < cs.length; i++) {
System.out.println(cs[i]);
}
}
} 我们能看到上面的例子有两种获取对象的方法,一种是newInstance,一种是getConstructors,那么这两种有什么区别呢? newInstance()方法, 只能通过空参的构造方法创建对象 getConstructor(Class<T>… parameterTypes)方法, 方法接受一个可变参数, 可以根据传入的类型来匹配对应的构造方法 今天先给大家讲到这,大家先理解反射的概念和如何通过字节码文件获取对象,下一章我们继续讲解如何通过反射获取对象中的其他内容。
点进这个帖子的同学肯定是要奋发图强,学技术拿高薪的有志青年,这里我看你骨骼惊奇,是个绝世的练武奇才,你我有缘,今天我就把这个武林秘籍如来神掌传授于你! 什么?不想学如来神掌?不要紧!这里有各个门派的武林绝学,链接拿好!!哈哈哈哈 |