您的位置:首页 > 编程语言 > Java开发

黑马学习笔记_Java 反射技术

2015-08-12 18:32 561 查看
  ——- android培训java培训、期待与您交流! ———-

反射

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);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: