------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------
-反射的概念
反射就是吧Java类中的各种成分映射成相应的Java类,例如一个Java类中用一个Class类的对象表示,一个类中的组成部分:成员变量,方法,构造方法,包等等信息也用一个个的Java类来表示,比如汽车是一个类,汽车中的发动机,变速箱等等也是一个个的类。表示Java的Class类显然要提供一系列的方法,来获得其中的变量、方法、构造方法,修饰符、包等信息,这些信息就是用相应的类的实例对象来表示,他们是Field、Method、Contructor、Package等等。
一个类中的每个成员都可以用相应的反射API类的一个实例对象来表示。
反射的主要应用:工具,架构,动态开发等开发工程。
-反射机制
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。简单说:反射技术可以对一个类进行解剖。
反射的好处:大大的增强了程序的扩展性。
-反射的基本步骤
1、获得Class对象,就是获取到指定的名称的字节码文件对象。
2、获得类的成员变量对象、成员方法对象或构造方法对象。
3、访问成员变量、调用方法、调用构造函数创建实例对象。
-反射的基础-Class类
Class类:Java程序中的各个Java类属于同一类事物,描述这类事物的Java类名就是Class
获取各个类字节码的方法有以下3种方式:
1、类名.class //直接使用类.class 获取
2、对象.getClass() //通过对象调用其getClass()方法获取
3、Class.forName("java.util.Date") //使用类加载器加载获取
public class Demo {
public static void main(String[] args) throws ClassNotFoundException {
//1:获取类 (字节码)的方法一
Class clazz1= Class.forName("reflect.Person");
//2:获取类 (字节码)的方法二
Class clazz2= new Person().getClass();
//3:获取类 (字节码)的方法三
Class clazz3= Person.class;
}
}
(小提示----Java原始基本类型有:boolean,byte, char, short, int, long, float, double, 另外关键词void同样有Class类,它们都可以通过( .class )获取它们的字节码)
-构造方法的反射应用
Constructor类:各种类构造方法的反射类
Constructor反射类对象的获取:
(例如) Constructor construtor = String.class.getConstrutor(StringBuffer.class);
从而可以通过构造方法创建实例对象:
String str = (String)construtor.newInstance(new StringBuffer("abc"));
Class 本身也有newInstance()方法,可以直接调用:
String obj = (String)String.class.newInstance(); //相当于调用无参的构造方法
package reflect;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
/**
* 反射类的构造函数,创建类对象
*
* @author Administrator
*
*/
public class ReflectConstrustor {
// 反射构造函数:public Person()
@Test
public void test1() throws Exception {
Class clazz = Class.forName("reflect.Person");
Constructor c = clazz.getConstructor(null);
Person p = (Person) c.newInstance(null);
System.out.println(p.name);
}
// 反射构造函数:public Person(String name)
@Test
public void test2() throws Exception {
Class clazz = Class.forName("reflect.Person");
Constructor c = clazz.getConstructor(String.class);
Person p = (Person) c.newInstance("haha");
System.out.println(p.name);
}
// 反射构造函数:public Person(String name,int password)
@Test
public void test3() throws Exception {
Class clazz = Class.forName("reflect.Person");
Constructor c = clazz.getConstructor(String.class, int.class);
Person p = (Person) c.newInstance("kila", 888);
System.out.println(p.name);
}
// 反射构造函数:public Person(List list)
@Test
public void test4() throws Exception {
Class clazz = Class.forName("reflect.Person");
Constructor c = clazz.getDeclaredConstructor(List.class);
c.setAccessible(true);
Person p = (Person) c.newInstance(new ArrayList());
System.out.println(p.name);
}
}
Person类:
package reflect;
import java.io.InputStream;
import java.util.List;
//关联学习反射的Person类
public class Person {
// 字段
public String name = "kolen.j";
private int password= 123;
private static int age= 27;
// 构造方法
public Person() {
System.out.println("Person()");
}
public Person(String name) {
System.out.println("Person(String name) ::" + name);
}
public Person(String name, int password) {
System.out.println("Person(String name,int password) ::" + name + ":"
+ password);
}
private Person(List list) {
System.out.println("Person(List list)");
}
// 非构造方法
public void person1() {
System.out.println("person1()");
}
public void person1(String name, int password) {
System.out.println(name + ":" + password);
}
public Class[] person1(String name, int[] phone) {
return new Class[] { String.class };
}
private void person1(InputStream in) {
System.out.println(in);
}
public static void person1(int num) {
System.out.println(num);
}
public static void main(String[] args){
System.out.println("main(String[] args)");
}
}
-Method:代表某个类中的一个成员方法
调用方法:
System.out.println(str.charAt());
System.out.println(charAt.invoke(str,1));
提供关于类或接口上单独某个方法(以及如何访问该方法)的信息。所反映的方法可能是类方法或实例方法(包括抽象方法)。
package reflect;
import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.Method;
import org.junit.Test;
/**
* 反射类的的非构造方法
*
* @author Administrator
*
*/
public class ReflectMethod {
Person p = null;
// 反射类的非构造方法:public void person1()
@Test
public void test1() throws Exception {
p = new Person();
Class clazz = Class.forName("reflect.Person");
Method method = clazz.getMethod("person1", null);
method.invoke(p, null);
}
// 反射类的非构造方法:public void Person1(String name, int password)
@Test
public void test2() throws Exception {
p = new Person();
Class clazz = Class.forName("reflect.Person");
Method method = clazz.getMethod("person1", String.class, int.class);
method.invoke(p, "kolen.j", 1111);
}
// 反射类的非构造方法:public Class[] Person1(String name, int[] phone)
@Test
public void test3() throws Exception {
p = new Person();
Class clazz = Class.forName("reflect.Person");
Method method = clazz.getMethod("person1", String.class, int[].class);
Class cl[] = (Class[]) method.invoke(p, "kolen.j", new int[] { 1, 2 });
System.out.println(cl[0]);
}
// 反射类的非构造方法:public void Person1(InputStream in)
@Test
public void test4() throws Exception {
p = new Person();
Class clazz = Class.forName("reflect.Person");
Method method = clazz.getDeclaredMethod("person1", InputStream.class);
method.setAccessible(true);
method.invoke(
p,
new FileInputStream(
"D:\\AppDev\\WorkSpace\\JavaSpace\\java\\src\\reflect\\reflectStudy.txt"));
}
// 反射类的非构造方法:public static void Person1(int num)
@Test
public void test5() throws Exception {
Class clazz = Class.forName("reflect.Person");
Method method = clazz.getMethod("person1", int.class);
method.invoke(null, 27);
}
// 反射类的Main()方法:public static void main(String[] args)
@Test
public void testMain() throws Exception {
//产生这个问题的原因是新版本要兼容以前的版本,分析如下
//jdk1.5 Method.invoke(String methodName,Object...args);
//jdk1.4 Method.invoke(String methodName,Object obj[]); a(String name,String password)
//jdk1.4 Method.invoke(String methodName,new Object[]{"aaa","123123"});
Class clazz = Class.forName("reflect.Person");
Method method= clazz.getMethod("main", String[].class);
//method.invoke(null, new String[]{"aa","bb"});//出错 ----main(String s1,String s2);
//method.invoke(null, new Object[]{new String[]{"aa","bb"}});//也可以像下面的写法
method.invoke(null, (Object)new String[]{"aa","bb"});
}
}
-字段的反射
Field:代表某个类中的一个成员变量
提供有关类或接口的单个字段的信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)字段或实例字段。
Array 允许在执行 get 或 set 访问操作期间进行扩展转换,但如果将发生收缩转换,则抛出一个 IllegalArgumentException。
package reflect;
import java.lang.reflect.Field;
import org.junit.Test;
/**
* 反射类的字段
*
* @author Administrator
*
*/
public class ReflectField {
Person p = null;
// 反射字段:public String name="kelon.j"
@Test
public void test1() throws Exception {
/*
* p= new Person(); Class clazz= Class.forName("reflect.Person"); Field
* f= clazz.getField("name"); String name= (String) f.get(p);
* System.out.println(name);
*
* //获取字段的类型 Class type= f.getType(); System.out.println(type);
*/
p = new Person();
Class clazz = Class.forName("reflect.Person");
Field f = clazz.getField("name");
// 获取字段的值
Object value = f.get(p);
// 获取字段的类型
Class type = f.getType();
// 判断字段的类似是否为某种期望的类型
if (type.equals(String.class)) {
String v = (String) value;
System.out.println(v);
}
// 设置字段的值
f.set(p, "xxx");
System.out.println(p.name);
}
// 反射字段:private int password;
@Test
public void test2() throws Exception {
p = new Person();
Class clazz = Class.forName("reflect.Person");
Field f = clazz.getDeclaredField("password");
f.setAccessible(true);
System.out.println(f.get(p));
}
// 反射字段:private static int age= 27;
@Test
public void test3() throws Exception {
// 字段的静态成员变量与静态方法 有点不一样,静态方法不用对象
// p= new Person();
Class clazz = Class.forName("reflect.Person");
Field f = clazz.getDeclaredField("age");
f.setAccessible(true);
System.out.println(f.get(p));
}
}