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深拷贝和浅拷贝

  3. 序列化与反序列化
    ```java
    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(); 
    }
    ```
  4. 反射
    ```java
    //第四种 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();
        System.out.println(c1.getName());
        
        Class c2 = Class.forName("java.lang.String");
        System.out.println(c2.getName());
        
        Class c3 = String.class;
        System.out.println(c3.getName());   

    }

}

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

  1. 反射得到方法
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;
    }
}
  1. 反射得到构造函数
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);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值