JAVA反射基础

1. 反射的定义:

  1. 在运行中分析类的能力
  2. 在运行中可以查看与操作对象:基于反射自由创建对象,反射构建无法直接访问的类方法属性
  3. 实现通用的数组操作代码
  4. 类似函数指针的功能

2. java创建对象的方法

  1. new一个对象

  2. 克隆(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();
    	}
    }
    

java深拷贝和浅拷贝

  1. 序列化与反序列化

    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(); 
    }
    
  2. 反射

            //第四种  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对象的方式:

  1. 通过String.getClass方法,获取Class对象

  2. 通过Class.forName("类的全限定名")

  3. 通过类字面常量,即类名.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的常用方法

  1. 反射得到父类以及接口

    
    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;
    }
    }
    
  2. 反射得成员变量

    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;
    }
    }
    
  3. 反射得到方法

    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;
    }
    }
    
  4. 反射得到构造函数

    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);
    }
    }
    
posted @ 2020-02-25 14:53  Ysalng  阅读(534)  评论(0编辑  收藏  举报