——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-
Class类
定义:Java中有一个Class类用于代表某一个类的字节码。
Class类既然代表某个类的字节码,当然就要提供加载某个类字节码的方法,用于将某个类的字节码加载到内存中,并使用class对象进行封装。
获取class对象的三种方式:
1.forName();
2.类名.class;
3.对象.getClass();
反射
定义:一个类有多个组成部分,例如:成员变量,构造方法,方法等。反射就是加载类,解剖类的各个组成部分。
下面一个例子演示下列反射过程
要反射的类Person
package reflect_01;
import java.io.InputStream;
import java.util.List;
public class Person {
// 字段
public String name = "daideng";
private String sex = "boy";
// 构造方法
public Person(){
System.out.println("Person无参构造方法");
}
public Person(String name){
System.out.println("Person name:"+name);
}
public Person(String name,int age){
System.out.println(name+":"+age);
}
private Person(List list){
System.out.println("list");
}
// 方法
public void run(){
System.out.println("run");
}
public void run(String name,int age){
System.out.println(name+":"+age);
}
public Class[] run(String name,int[] age){
return new Class[]{String.class};
}
private void run(InputStream in){
System.out.println(in);
}
public static void run(int num){
System.out.println(num);
}
public static void main(String[] args){
System.out.println("main");
}
}
- 反射类的构造方法
package reflect_01;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
//反射类的构造函数,创建类的对象
public class Demo1 {
// 反射构造函数: public Person()
@Test
public void test1() throws Exception{
// 加载类,获取类的class对象
Class clazz = Class.forName("reflect_01.Person");
// 获取构造方法
Constructor c = clazz.getConstructor(null);
// 创建实例
Person p = (Person) c.newInstance(null);
}
// 反射构造函数: public Person(String name)
@Test
public void test2() throws Exception{
// 加载类,获取类的class对象
Class clazz = Class.forName("reflect_01.Person");
// 获取构造方法
Constructor c = clazz.getConstructor(String.class);
// 创建实例
Person p = (Person) c.newInstance("老鸭");
}
// 反射构造函数: public Person(String name,int age)
@Test
public void test3() throws Exception{
// 加载类,获取类的class对象
Class clazz = Class.forName("reflect_01.Person");
// 获取构造方法
Constructor c = clazz.getConstructor(String.class,int.class);
// 创建实例
Person p = (Person) c.newInstance("老鸭",29);
}
// 反射构造函数:private Person(List list)
@Test
public void test4() throws Exception{
// 加载类,获取类的class对象
Class clazz = Class.forName("reflect_01.Person");
// 获取构造方法
// 由于构造方法是私有方法,所以获取时用getDeclaredConstructor(),并进行暴力反射
Constructor c = clazz.getDeclaredConstructor(List.class);
c.setAccessible(true);//暴力反射
// 创建实例
Person p = (Person) c.newInstance(new ArrayList());
}
// 获取类对象的另一种方式 ---等同于test1();
// 反射构造函数: public Person()
@Test
public void test5() throws Exception{
// 加载类,获取类的class对象
Class clazz = Class.forName("reflect_01.Person");
// 由于构造方法的参数是null,所以不用获取构造方法,直接创建实例。
// 创建实例
Person p = (Person) clazz.newInstance();
}
}
2.反射类的方法
package reflect_01;
import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.Method;
import org.junit.Test;
//反射方法
public class Demo2 {
// 反射方法:public void run()
@Test
public void test1() throws Exception{
Person p = new Person();
Class clazz = Class.forName("reflect_01.Person");
Method method = clazz.getMethod("run", null);
method.invoke(p, null);
}
// 反射方法:public void run(String name,int age)
@Test
public void test2() throws Exception{
Person p = new Person();
Class clazz = Class.forName("reflect_01.Person");
Method method = clazz.getMethod("run", String.class,int.class);
method.invoke(p, "lisi",22);
}
// 反射方法:public Class[] run(String name,int[] age)
@Test
public void test3() throws Exception{
Person p = new Person();
Class clazz = Class.forName("reflect_01.Person");
Method method = clazz.getMethod("run", String.class,int[].class);
Class[] cs = (Class[]) method.invoke(p, "zhangsan",new int[]{1,3,4});
System.out.println(cs[0]);
}
// 反射方法: private void run(InputStream in)
@Test
public void test4() throws Exception{
Person p = new Person();
Class clazz = Class.forName("reflect_01.Person");
Method method = clazz.getDeclaredMethod("run", InputStream.class);
method.setAccessible(true);
method.invoke(p, new FileInputStream("g:/Demo.java"));
}
// 反射方法:public static void run(int num)
@Test
public void test5() throws Exception{
Person p = new Person();
Class clazz = Class.forName("reflect_01.Person");
Method method = clazz.getMethod("run", int.class);
method.invoke(null, 30);
}
// 反射方法: public static void main(String[] args)
@Test
public void test6() throws Exception{
Person p = new Person();
Class clazz = Class.forName("reflect_01.Person");
Method method = clazz.getMethod("main", String[].class);
method.invoke(p, new Object[]{new String[]{"lisi"}});
}
}
3.反射类的字段(也叫属性)
package reflect_01;
import java.lang.reflect.Field;
import org.junit.Test;
//反射字段
public class Demo3 {
// 反射字段:public String name = "daideng";
@Test
public void test1() throws Exception{
Person p = new Person();
Class clazz = Class.forName("reflect_01.Person");
Field field = clazz.getField("name");
// 获取字段的值
Object value = field.get(p);
// 获取字段的类型
Class type = field.getType();
if (type.equals(String.class)) {
String svalue = (String)value;
System.out.println(svalue);
}
// 设置字段的值
field.set(p, "ccccc");
System.out.println(p.name);
}
// 反射字段:private String sex = "boy";
@Test
public void test2() throws Exception{
Person p = new Person();
Class clazz = Class.forName("reflect_01.Person");
Field field = clazz.getDeclaredField("sex");
field.setAccessible(true);//对私有变量进行暴力反射
Object value = field.get(p);
Class c = field.getType();
if (c.equals(String.class)) {
String svalue = (String)value;
System.out.println(svalue);
}
}
}