反射

反射技术主要是用来做框架

一个类有多个组成部分,例如:成员变量,方法,构造方法等。反射就是加载类,并解剖出类的各个组成部分。

编程时什么情况下才需要加载类,并解剖出类的各个组成部分呢?

1、加载类
Java中有一个Class类用于代表某一个类的字节码。

Class类即然代表有个类的字节码,它当然就要提供加载某个类字节码的方法:forName()。forName方法用于加载某个类的字节码到内存中,并使用class对象进行封装

另外两种得到class对象的方式
类名.class
对象.getClass()

2、解剖类
Class对象提供了如下常用方法:
Public Constructor getConstructor(Class<?>...parameterTypes) //获得公共构造函数
Public Method getMethod(String name,Class<?>...parameterTypes) //获得公共方法
Public Field getField(String name) //获得公共属性

public Constructor getDeclaredConstructor(Class<?>...parameterTypes) //获得所有构造函数
public Method getDeclaredMethod(String name,Class<?>...parameterTypes) //获得所有方法
public Field getDeclaredField(String name) //获得所有属性

这些方法分别用于从类中解剖出构造函数、方法和成员变量(属性)。解剖出的成员分别使用Constructor、Method、Field对象表示。

3、利用Constructor创建对象
Constructor类提供了如下方法,用于创建类的对象:
public Object newInstance(Object... initargs)
initargs用于指定构造函数接收的参数

多学一招:sun公司为简化开发人员创建对象,它class对象中也提供了一个newInstance方法,用于创建类的对象。这样开发人员可以避免每次都需要去反射Constructor类以创建对象。

不过需要注意的是:class.newInstance方法内部是反射类无参的构造函数创建的对象,所以利用此种方式创建类对象时,类必须有一个无参的构造函数。

4、利用Method执行方法
Method对象提供了如下方法,用于执行它所代表的方法:
public Object invoke(Object obj,Object... args)
jdk1.4和jdk1.5的invoke方法的区别
jdk1.5:public Object invoke(Object obj,Object... args)
jdk1.4:public Object invoke(Object obj,Object[] args)

5、

代码1(Person类):

package cn.itcast.reflect;

import java.io.InputStream;
import java.util.List;

public class Person {
public String name = "aaa";
private int password=123;
private static int age=23;

public Person() {
System.out.println("person");
}

public Person(String name) {
System.out.println(name);
}

public Person(String name, int password) {
System.out.println(name + ":" + password);
}

private Person(List list) {
System.out.println("list");
}

public void aa1() {
System.out.println("aa1");
}

public void aa1(String name, int password) {
System.out.println(name + ":" + password);
}

public Class[] aa1(String name, int[] password) {
return new Class[] { String.class };
}

private void aa1(InputStream in) {
System.out.println(in);
}

public static void aa1(int num) {
System.out.println(num);
}

public static void main(String[] args) {
System.out.println("main!!");
}
}

代码2(Demo1类):

package cn.itcast.reflect;

public class Demo1 {

/**
* 反射:加载类
*
* @param args
* @throws ClassNotFoundException
*/
public static void main(String[] args) throws ClassNotFoundException {

// 1.
Class clazz = Class.forName("cn.itcast.reflect.Person");

// 2.
Class clazz1 = new Person().getClass();

// 3.
Class clazz2 = Person.class;

}

}

代码3(Demo2类):

package cn.itcast.reflect;

import java.lang.reflect.Constructor;

import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

//解剖类的构造函数,创建类的对象
public class Demo2 {

// 反射构造函数:public Person()
@Test
public void test1() throws Exception {
Class clazz = Class.forName("cn.itcast.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("cn.itcast.reflect.Person");
Constructor c = clazz.getConstructor(String.class);
Person p = (Person) c.newInstance("xxxxxx");
System.out.println(p.name);
}

// 反射构造函数:public Person(String name,int password)
@Test
public void test3() throws Exception {
Class clazz = Class.forName("cn.itcast.reflect.Person");
Constructor c = clazz.getConstructor(String.class, int.class);
Person p = (Person) c.newInstance("yyy", 112);
System.out.println(p.name);
}

// 反射构造函数:public Person(List list)
@Test
public void test4() throws Exception {
Class clazz = Class.forName("cn.itcast.reflect.Person");
Constructor c = clazz.getDeclaredConstructor(List.class);
c.setAccessible(true);// 暴力反射
Person p = (Person) c.newInstance(new ArrayList());
System.out.println(p.name);
}

// 创建对象的另外一种途径:以下代码,等效于test1
@Test
public void test5() throws Exception {
Class clazz = Class.forName("cn.itcast.reflect.Person");
Person p = (Person) clazz.newInstance();
System.out.println(p.name);
}
}

代码4(Demo3类):

package cn.itcast.reflect;

import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.Method;

import org.junit.Test;

//反射类的方法
public class Demo3 {

// 反射类的方法:public void aa1()
@Test
public void test1() throws Exception {
Person p = new Person();
Class clazz = Class.forName("cn.itcast.reflect.Person");
Method method = clazz.getMethod("aa1", null);
method.invoke(p, null);
}

// 反射类的方法:public void aa1(String name,int password)
@Test
public void test2() throws Exception {
Person p = new Person();
Class clazz = Class.forName("cn.itcast.reflect.Person");
Method method = clazz.getMethod("aa1", String.class, int.class);
method.invoke(p, "zxx", 38);
}

// 反射类的方法:public void aa1(String name,int password)
@Test
public void test3() throws Exception {
Person p = new Person();
Class clazz = Class.forName("cn.itcast.reflect.Person");
Method method = clazz.getMethod("aa1", String.class, int[].class);
Class cs[] = (Class[]) method.invoke(p, "zxx", new int[] { 1, 2, 3 });
System.out.println(cs[0]);
}

// 反射类的方法:private void aa1(InputStream in)
@Test
public void test4() throws Exception {
Person p = new Person();
Class clazz = Class.forName("cn.itcast.reflect.Person");
Method method = clazz.getDeclaredMethod("aa1", InputStream.class);
method.setAccessible(true);
method.invoke(p,new FileInputStream("c:\1.txt"));
}

// 反射类的方法:public static void aa1(int num)
@Test
public void test5() throws Exception {
Class clazz = Class.forName("cn.itcast.reflect.Person");
Method method = clazz.getMethod("aa1", int.class);
method.invoke(null,11);
}

// 反射类的方法:public static void main(String[] args)
@Test
public void test6() throws Exception {
Class clazz = Class.forName("cn.itcast.reflect.Person");
Method method = clazz.getMethod("main", String[].class);
method.invoke(null,new Object[]{new String[]{"aa","bb"}});

method.invoke(null,(Object)new String[]{"aa","bb"});

//jdk1.5 Method.invoke(String methodName,Object... args); 为了兼容之前的版本,遇到数组会拆
//jdk1.4 Method.invoke(String methodName,Object args[]);
}
}

代码5(Demo4类):

package cn.itcast.reflect;

import java.lang.reflect.Field;

import org.junit.Test;

//反射字段
public class Demo4 {

// 反射字段:public String name = "aaa";
@Test
public void test1() throws Exception {
Person p=new Person();
Class clazz = Class.forName("cn.itcast.reflect.Person");
Field f=clazz.getField("name");
//获取字段的值
Object obj=f.get(p);
//获取字段的类型
Class type=f.getType();
if(type.equals(String.class)){
String value=(String)obj;
System.out.println(value);
}

//设置字段的值
f.set(p, "xxxx");
System.out.println(p.name);
}

// 反射字段:private int password;
@Test
public void test2() throws Exception {
Person p=new Person();
Class clazz = Class.forName("cn.itcast.reflect.Person");
Field f=clazz.getDeclaredField("password");
f.setAccessible(true);
System.out.println(f.get(p));
}

// 反射字段:private static int age;
@Test
public void test3() throws Exception {
Person p=new Person();
Class clazz = Class.forName("cn.itcast.reflect.Person");
Field f=clazz.getDeclaredField("age");
f.setAccessible(true);
System.out.println(f.get(p));
}
}

原文地址:https://www.cnblogs.com/xiaohuihui123/p/4359046.html