黑马程序员技术交流社区

标题: 【黑马程序员济南】小鲁哥哥白话笔记-反射 [打印本页]

作者: 小鲁哥哥    时间: 2017-8-24 15:23
标题: 【黑马程序员济南】小鲁哥哥白话笔记-反射
本帖最后由 小鲁哥哥 于 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);
}
}
}
我们能看到上面的例子有两种获取对象的方法,一种是newInstance,一种是getConstructors,那么这两种有什么区别呢?
newInstance()方法, 只能通过空参的构造方法创建对象
getConstructor(Class<T>… parameterTypes)方法, 方法接受一个可变参数, 可以根据传入的类型来匹配对应的构造方法
今天先给大家讲到这,大家先理解反射的概念和如何通过字节码文件获取对象,下一章我们继续讲解如何通过反射获取对象中的其他内容。

点进这个帖子的同学肯定是要奋发图强,学技术拿高薪的有志青年,这里我看你骨骼惊奇,是个绝世的练武奇才,你我有缘,今天我就把这个武林秘籍如来神掌传授于你! 什么?不想学如来神掌?不要紧!这里有各个门派的武林绝学,链接拿好!!哈哈哈哈
     【黑马程序员济南】小鲁哥哥全学科技术整合帖(一贴在手!天下我有!)

作者: jingxian90    时间: 2017-9-11 08:55
挺厉害,学到了




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2