JAVA反射基础
1. 反射的定义:
- 在运行中分析类的能力
- 在运行中可以查看与操作对象:基于反射自由创建对象,反射构建无法直接访问的类方法属性
- 实现通用的数组操作代码
- 类似函数指针的功能
2. java创建对象的方法
-
new一个对象
-
克隆(clone),实现Cloneable接口:
public class B implements Cloneable { public void hello() { System.out.println("hello"); } protected Object clone() throws CloneNotSupportedException { return super.clone(); } public static void main(String[] args) throws Exception{ B obj2 = new B(); obj2.hello(); B obj3 = (B) obj2.clone(); obj3.hello(); } }
-
序列化与反序列化
public class C implements Serializable { private static final long serialVersionUID = 1L; //序列化要求有一个serialVersionUID public void hello() { System.out.println("hello"); } public static void main(String[] args) throws Exception{ //对象序列化 C obj4 = new C(); ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("data.obj")); out.writeObject(obj4); //写入 out.close(); ObjectInputStream in = new ObjectInputStream(new FileInputStream("data.obj")); C obj5 = (C) in.readObject(); //读取 in.close(); obj5.hello(); }
-
反射
//第四种 newInstance 调用构造函数 Object obj6 = Class.forName("A").newInstance(); Method m = Class.forName("A").getMethod("hello"); m.invoke(obj6); A obj7 = (A) Class.forName("A").newInstance(); obj7.hello(); //第五种 newInstance 调用构造函数 Constructor<A> constructor = A.class.getConstructor(); A obj8 = constructor.newInstance(); obj8.hello();
3. Class类
Class对象是在类加载的时候由Java虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的
3.1. 获取Class对象
有三种获得Class对象的方式:
-
通过String.getClass方法,获取Class对象
-
通过Class.forName("类的全限定名")
-
通过类字面常量,即类名.class
public class ClassTest {
public static void main(String[] args) throws ClassNotFoundException {
String s1 = "abc";
Class c1 = s1.getClass();//方法1
System.out.println(c1.getName());
Class c2 = Class.forName("java.lang.String");//方法2
System.out.println(c2.getName());
Class c3 = String.class;
System.out.println(c3.getName());//方法3
}
}
3.2. Class的常用方法
-
反射得到父类以及接口
public class SuperTest { public static void main(String[] args) { Son son = new Son(); Class c = son.getClass(); Class father = c.getSuperclass(); System.out.println(father.getName()); Class[] inters = c.getInterfaces(); for(Class inter : inters) { System.out.println(inter.getName()); } } } class Father { } class Son extends Father implements Cloneable, Comparable { protected Object clone() throws CloneNotSupportedException { return super.clone(); } public int compareTo(Object o) { return 0; } }
-
反射得成员变量
import java.lang.reflect.Field; public class FieldTest { public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException { A obj = new A(20, "Tom"); Class c = obj.getClass(); //获取本类及父类所有的public字段 Field[] fs = c.getFields(); System.out.println(fs[0].getName() + ":" + fs[0].get(obj)); //获取本类所有声明的字段 Field[] fs2 = c.getDeclaredFields(); for(Field f : fs2) { f.setAccessible(true); System.out.println(f.getName() + ":" + f.get(obj)); } } } class A { public int age; private String name; public A(int age, String name) { this.age = age; this.name = name; } }
-
反射得到方法
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import static java.lang.System.out; public class MethodTest { public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { B obj = new B(); Class c = obj.getClass(); // 获取public方法 包括父类和父接口 Method[] ms = c.getMethods(); for (Method m : ms) { if ("f1".equals(m.getName())) { m.invoke(obj, null); } } // 获得该类的所有方法 Method[] ms2 = c.getDeclaredMethods(); for (Method m : ms2) { if ("f2".equals(m.getName())) { m.setAccessible(true); String result = (String) m.invoke(obj, "abc"); out.println(result); } } } } class B { public void f1() { out.println("B.f1()..."); } private String f2(String s) { out.println("B.f2()..."); return s; } }
-
反射得到构造函数
import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; public class ConstructorTest { public static void main(String[] args) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { D d = new D(); Class c = d.getClass(); Constructor[] cons = c.getConstructors(); for (Constructor con : cons) { if (con.getParameterCount() > 0) { // 有参构造函数 D obj = (D) con.newInstance(100); obj.printNum(); } else { // 无参构造函数 D obj = (D) con.newInstance(); obj.printNum(); } } } } class D { private int num; public D() { this.num = 10; } public D(int num) { this.num = num; } public void printNum() { System.out.println(this.num); } }