黑马学习笔记_Java 反射技术
2015-08-12 18:32
561 查看
——- android培训、java培训、期待与您交流! ———-
java反射机制是运行状态中,对于任意一个类,都能够知道这类的所有属性和方法;
对于任意一个对像,都能够调用它的任意一个方法和属性;
这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制;
要想解剖一个类,必须先要获取到该类的字节码文件对象;
而解剖使用的就是Class类中的方法,所以先要获取到每一个字节码文件对应的Class类型的对象;
2 反射中常用的类
Class类:Class类十分特殊,当一个class被加载jvm便会自动产生一个Class对象。Class 类的实例表示正在运行的 Java 应用程序中的类和接口。基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也表示为 Class 对象。Class 没有公共构造方法
Field类:用户描述java类中的成员变量,
Method类:用户描述java类中的成员方法
Constructor 提供关于类的单个构造方法的信息以及对它的访问权限
3 反射的应用场景
反射是框架中常用的方法:
对于WEB框架,开发人员在配置文件中定义他们对各种接口和类的实现,通过反射机制,框架能够快速的动态初始化所需要的类。
例如,Spring框架使用如下的配置文件:
当Spring容器处理元素时,会使用Class.forName(“com.tplinking.domain”)来初始化这个类,并再次使用反射获取元素对应的setter方法,为对象的属性赋值。
Servlet也会使用相同的机制:
4 如何使用反射
让我们同过几个典型的案例来学习如何使用反射
实例1:获取字节码对象的3种方式
实例2:通过反射创建对象
实例3:通过反射调用类中的方法
实例4:通过反射调用类中的字段
反射
1 反射的概述java反射机制是运行状态中,对于任意一个类,都能够知道这类的所有属性和方法;
对于任意一个对像,都能够调用它的任意一个方法和属性;
这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制;
要想解剖一个类,必须先要获取到该类的字节码文件对象;
而解剖使用的就是Class类中的方法,所以先要获取到每一个字节码文件对应的Class类型的对象;
2 反射中常用的类
Class类:Class类十分特殊,当一个class被加载jvm便会自动产生一个Class对象。Class 类的实例表示正在运行的 Java 应用程序中的类和接口。基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也表示为 Class 对象。Class 没有公共构造方法
Field类:用户描述java类中的成员变量,
Method类:用户描述java类中的成员方法
Constructor 提供关于类的单个构造方法的信息以及对它的访问权限
3 反射的应用场景
反射是框架中常用的方法:
对于WEB框架,开发人员在配置文件中定义他们对各种接口和类的实现,通过反射机制,框架能够快速的动态初始化所需要的类。
例如,Spring框架使用如下的配置文件:
<bean id="someID" class="com.tplinking.domain"> <property name="someField" value="someValue"/> </bean>
当Spring容器处理元素时,会使用Class.forName(“com.tplinking.domain”)来初始化这个类,并再次使用反射获取元素对应的setter方法,为对象的属性赋值。
Servlet也会使用相同的机制:
<servlet> <servlet-name>someServlet</servlet-name> <servletclass> com.programcreek.WhyReflectionServlet </servlet-class> <servlet>
4 如何使用反射
让我们同过几个典型的案例来学习如何使用反射
package cn.itcast.bean; public class Student { public int age; public String name; public Student() { super(); System.out.println("construct Student run"); } public Student(int age, String name) { super(); this.age = age; this.name = name; System.out.println("construct Student param run...."); } public void show() { System.out.println(name + "...show run...." + age); } private void method() { System.out.println("method run"); } public void paramMethod(int num, String str) { System.out.println(num + "...paramMethod...." + str); } public static void staticMethod() { System.out.println("static method run...."); } }
实例1:获取字节码对象的3种方式
package cn.itcast.reflect.demo; import cn.itcast.bean.Student; public class Test { public static void main(String[] args) throws Exception { //通过该对象,调用object的getClass()方法来获取字节码文件对象 Student p1 = new Student(); Class<? extends Student> clazz1 = p1.getClass(); System.out.println(p1); //通过调用该类的class属性来获取字节码文件对象 Class clazz2 = Student.class; System.out.println(clazz2); //直接通过Class的forName()来获取该字符串表示的字节码文件对象 Class clazz3 = Class.forName("cn.itcast.bean.Student"); } }
实例2:通过反射创建对象
package cn.itcast.reflect.demo; import java.lang.reflect.Constructor; import cn.itcast.bean.Student; public class Test { public static void main(String[] args) throws Exception { //通过反射调用无参数的构造方法 Class clazz1 = Class.forName("cn.itcast.bean.Student"); Object object1 = clazz1.newInstance(); System.out.println(object1); //通过反射调用有参数的构造方法 Class<?> clazz2 = Class.forName("cn.itcast.bean.Student"); //获取构造方法对象 Constructor<?> constructor = clazz2.getConstructor(int.class, String.class); Object object2 = constructor.newInstance(2, "小强"); System.out.println(object2); } }
实例3:通过反射调用类中的方法
package cn.itcast.reflect.demo; import java.lang.reflect.Constructor; import java.lang.reflect.Method; public class Test { public static void main(String[] args) throws Exception { getMethodDemo(); } /** * 通过反射调用类中的有参方法 * @throws Exception */ public static void getMethodDemo_3() throws Exception { Class<?> clazz = Class.forName("cn.itcast.bean.Student"); Method method = clazz.getMethod("paramMethod", int.class, String.class); Object obj = clazz.newInstance(); method.invoke(obj, 89, "小强"); } /** * 获取空参数的成员方法 * @throws Exception */ public static void getMethodDemo_2() throws Exception { Class<?> clazz = Class.forName("cn.itcast.bean.Student"); Method method = clazz.getMethod("show", null);// 获取空参数一般方法。 // Object obj = clazz.newInstance(); Constructor constructor = clazz.getConstructor(int.class, String.class); Object obj = constructor.newInstance(37, "小明"); method.invoke(obj, null); } /** * 获取指定Class中的所有方法。 * @throws Exception */ public static void getMethodDemo() throws Exception { Class clazz = Class.forName("cn.itcast.bean.Student"); Method[] methods = clazz.getMethods();// 获取的都是公有的方法。 methods = clazz.getDeclaredMethods();// 只获取本类中所有方法,包含私有。 for (Method method : methods) { System.out.println(method); } } }
实例4:通过反射调用类中的字段
package cn.itcast.reflect.demo; import java.lang.reflect.Field; public class Test { /** * 通过反射获取类中的字段 * @param args * @throws Exception */ public static void main(String[] args) throws Exception { getFieldDemo(); } /** * 获取字节码文件中的字段。 * @throws Exception */ public static void getFieldDemo() throws Exception { Class<?> clazz = Class.forName("cn.itcast.bean.Student"); Field field = null;// clazz.getField("age");//只能获取公有的, field = clazz.getDeclaredField("age");// 只获取本类,但包含私有。 //创建对象 Object obj = clazz.newInstance(); //为对象中的成员变量赋值 field.set(obj, 89); //获取对象的中的成员变量的值 Object o = field.get(obj); System.out.println(o); } }
相关文章推荐
- Spring事务配置的五种方式
- java虚拟机
- 0000001_java学习之路
- hadoop eclipse 插件
- java, Hello World
- Java
- Java Servlet完全教程
- JAVA基础应用——使用sqlite3
- JAVA多线程两个实用的辅助类(CountDownLatch和AtomicBoolean)
- spring MVC中传递的参数对象中包含list的情况
- Java多线程——<七>多线程的异常捕捉
- Eclipse中集成Ant配置 (转)
- java反射机制详解 及 Method.invoke解释
- java动态反射调用方法
- java中如何反射获取一个类
- Java删除ArrayList中的重复元素的2种方法
- Java基础:常见对象
- java SSH网上拍卖平台系统
- MyEclipse 快捷键
- 【leetcode】Palindrome Linked List【java】