这个反射类是在网易云课堂上30天轻松掌握JavaWeb里面学习的。可以写框架用。但是为什么还要学呢?当然是为了用喽。
- 一个类有多个组成部分, 例如:成员变量,方法,构造方法。反射就算加载类, 并解剖出类的各个组成部分。
- Java中有一个Class类用于代表某一个类的字节码。Class类里有一个forName()方法,用于加载某个类的字节码到内存中,并用class对象进行封装。另外两种得到class对象的方式为
- 类名.class
- 对象.getClass()
- Class类常用方法
- public Constructor getConstructor: 反射出某个类的(public)构造函数
public Constructor getDeclaredConstructor: 反射出某个类的(private)构造函数 - public Metod getMethod: 反射出某个类的(public)方法
public Metod getDeclareMethod: 反射出某个类的(private)方法 - public Field getField: 反射出某个类的(public)字段也就是属性
public Field getDeclaredField: 反射出某个类的(private)字段也就是属性
- public Constructor getConstructor: 反射出某个类的(public)构造函数
下面是案例:
- 新建一个Person类
package com.test.reflect;
import java.io.InputStream;
import java.util.List;
public class Person {
public String name = "张三";
private int password = 666;
private static int age = 6;
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 run() {
System.out.println("run");
}
public void run(String name, int password) {
System.out.println(name + ":" + password);
}
public Class[] run(String name, int[] password) {
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");
}
}
- 反射中加载类,获得类的字节码的3个方法
package com.test.reflect;
public class Demo {
public static void main(String[] args) throws ClassNotFoundException {
//1:
Class clazz = Class.forName("com.test.reflect.Person");
//2:
Class clazz1 = new Person().getClass();
//3:
Class clazz2 = Person.class;
}
}
- 反射构造函数
package com.test.reflect;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
public class Demo1 {
//这里先不管他,直接看下一个
@Test
public Person test() throws Exception {
Class<?> clazz = Class.forName("com.test.reflect.Person");
Constructor<?> constructor = clazz.getConstructor();
Person p = (Person) constructor.newInstance();
return p;
}
//反射构造函数: public Person()
@Test
public void test1() throws Exception {
Class<?> clazz = Class.forName("com.test.reflect.Person");
Constructor<?> constructor = clazz.getConstructor();
Person p = (Person) constructor.newInstance();
System.out.println(p.name);
}
//反射构造函数:public Person(String name)
@Test
public void test2() throws Exception {
Class<?> clazz = Class.forName("com.test.reflect.Person");
Constructor<?> constructor = clazz.getConstructor(String.class);
Person p = (Person) constructor.newInstance("Stars");
System.out.println(p.name);
}
//反射构造函数:public Person(String name, int password)
@Test
public void test3() throws Exception {
Class<?> clazz = Class.forName("com.test.reflect.Person");
Constructor<?> constructor = clazz.getConstructor(String.class, int.class);
Person p = (Person) constructor.newInstance("Stars", 666);
System.out.println(p.name);
}
//反射构造函数:public Person(List list)
@Test
public void test4() throws Exception {
Class<?> clazz = Class.forName("com.test.reflect.Person");
Constructor<?> constructor = clazz.getDeclaredConstructor(List.class);
constructor.setAccessible(true);
Person p = (Person) constructor.newInstance(new ArrayList());
System.out.println(p.name);
}
//反射构造函数另一种方法 注意只能是无参构造函数
@Test
public void test5() throws Exception {
Class<?> clazz = Class.forName("com.test.reflect.Person");
Person p = (Person) clazz.newInstance();
System.out.print(p.name);
}
}
- 反射方法
package com.test.reflect;
import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.Method;
import org.junit.Test;
public class Demo2 {
// Demo1 demo1 = new Demo1();
// Person p = demo1.test();
Person p = new Person();
//反射类的方法: public void run()
@Test
public void test1() throws Exception {
Class<?> clazz = Class.forName("com.test.reflect.Person");
Method method = clazz.getMethod("run");
method.invoke(p);
}
//反射类的方法: public void run(String name, int password)
@Test
public void test2() throws Exception {
Class<?> clazz = Class.forName("com.test.reflect.Person");
Method method = clazz.getMethod("run", String.class, int.class);
method.invoke(p, "abcd", 6666);
}
//反射类的方法: public Class[] run(String name, int[] password)
@Test
public void test3() throws Exception {
Class<?> clazz = Class.forName("com.test.reflect.Person");
Method method = clazz.getMethod("run", String.class, int[].class);
Class[] cs = (Class[]) method.invoke(p, "efgh", new int[]{1,2});
System.out.println(cs[0]);
}
//反射类的方法: private void run(InputStream in)
@Test
public void test4() throws Exception {
Class<?> clazz = Class.forName("com.test.reflect.Person");
Method method = clazz.getDeclaredMethod("run", InputStream.class);
method.setAccessible(true);
method.invoke(p, new FileInputStream("D:\\1.txt")); //1.txt 必须存在
}
//反射类的方法: public static void run(int num)
@Test
public void test5() throws Exception {
Class<?> clazz = Class.forName("com.test.reflect.Person");
Method method = clazz.getMethod("run", int.class);
// method.invoke(null, 666);
method.invoke(p, 666); //这两个都可以
}
//反射类的方法: public static void run(int num)
@Test
public void test6() throws Exception {
Class<?> clazz = Class.forName("com.test.reflect.Person");
Method method = clazz.getMethod("main", String[].class);
// method.invoke(null, new Object[]{new String[]{}}); //这两个都可以
method.invoke(null, (Object)new String[]{}); //null 可以换成p对象,
}
}
- 反射字段
package com.test.reflect;
import java.lang.reflect.Field;
import org.junit.Test;
//反射字段
public class Demo3 {
//反射字段 public String name = "张三";
@Test
public void test1() throws Exception {
Person p = new Person();
Class<?> clazz = Class.forName("com.test.reflect.Person");
Field f = clazz.getField("name");
//获取字段的值
Object value = f.get(p);
//获取字段的类型
Class<?> type = f.getType();
if (type.equals(String.class)) { //这是两个对象比较
value = (String)value;
System.out.println(value);
}
//设置字段的值
f.set(p, "stars");
System.out.println(p.name);
}
//反射字段 private int password = 666;
@Test
public void test2() throws Exception {
Person p = new Person();
Class<?> clazz = Class.forName("com.test.reflect.Person");
Field f = clazz.getDeclaredField("password");
f.setAccessible(true);
System.out.println(f.get(p));
}
//反射字段 private static int age = 6; //跟非静态字段一样
@Test
public void test3() throws Exception {
Person p = new Person();
Class<?> clazz = Class.forName("com.test.reflect.Person");
Field f = clazz.getDeclaredField("age");
f.setAccessible(true);
System.out.println(f.get(p));
}
}
写在最后: 写这篇博客的目的是为了巩固自己学的知识,毕竟看的总比不过自己手敲一遍代码来的实在,以后决定每学一个知识点都要写博客巩固一下