Java反射

定义:
Java反射机制是指在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
用一句话总结就是反射可以实现在运行时可以知道任意一个类的属性和方法。

Class类和类类型:
通过已有的类得到它的Class对象,共有三种方式:

package Reflect;
class Demo{
    //other codes...
}
 
class hello{
    public static void main(String[] args) {
        Class demo1=null;
        Class demo2=null;
        Class demo3=null;
        try{
            //一般尽量采用这种形式
            demo1=Class.forName("Reflect.Demo");
        }catch(Exception e){
            e.printStackTrace();
        }
        demo2=new Demo().getClass();
        demo3=Demo.class;
         
        System.out.println("类名称   "+demo1.getName());
        System.out.println("类名称   "+demo2.getName());
        System.out.println("类名称   "+demo3.getName());
         
    }
}

运行结果:

类名称   Reflect.Demo
类名称   Reflect.Demo
类名称   Reflect.Demo

获取构造函数Constructor:
Person类,定义了几个构造方法:

package Reflect;
import java.lang.reflect.Constructor;
class Person{
     
    public Person() {
         
    }
    public Person(String name){
        this.name=name;
    }
    public Person(int age){
        this.age=age;
    }
    public Person(String name, int age) {
        this.age=age;
        this.name=name;
    }
    public String getName() {
        return name;
    }
    public int getAge() {
        return age;
    }
    @Override
    public String toString(){
        return "["+this.name+"  "+this.age+"]";
    }
    private String name;
    private int age;
}

通过无参构造实例化对象:
在加上有参构造函数后,默认无参构造函数失效,一定要添上无参构造函数。

demo=Class.forName("Reflect.Person");
per=(Person)demo.newInstance();
per.setName("Rollen");
per.setAge(20);

通过反射:

demo=Class.forName("Reflect.Person");

Person per1=null;
Person per2=null;
Person per3=null;
Person per4=null;
//取得全部的构造函数
Constructor cons[]=demo.getConstructors();

per1=(Person)cons[0].newInstance();
per2=(Person)cons[1].newInstance("Rollen");
per3=(Person)cons[2].newInstance(20);
per4=(Person)cons[3].newInstance("Rollen",20);

System.out.println(per1);
System.out.println(per2);
System.out.println(per3);
System.out.println(per4);

获取成员方法Method:

  • public Methods = getDeclaredMethods(); // 得到该类所有的方法,不包括父类的。
  • public Methods = getMethods();// 得到该类所有的public方法,包括父类的。
public class Person {
    private String name;
    private int age;
    private String msg="hello wrold";
    public String getName() {
       return name;
    }

    public void setName(String name) {
       this.name = name;
    }

    public int getAge() {
       return age;
    }

    public void setAge(int age) {
       this.age = age;
    }

    public Person() {
    }

    private Person(String name) {
       this.name = name;
    System.out.println(name);
    }

    public void fun() {
       System.out.println("fun");
    }

    public void fun(String name,int age) {
       System.out.println("我叫"+name+",今年"+age+"岁");
    }
}

public class ReflectDemo {
    public static void main(String[] args){
       try {
           Class c = Class.forName("Reflect.Person");
           Object o = c.newInstance();
           Method method = c.getMethod("fun", String.class, int.class);
           method.invoke(o, "aaa", 10);
       } catch (Exception e) {
           e.printStackTrace();
       }
    }
}

执行结果:

我叫aaa,今年10岁
  • Method[] methods = c.getDeclaredMethods(); // 得到该类所有的方法,不包括父类的。
  • Method[] methods = c.getMethods();// 得到该类所有的public方法,包括父类的。
public class ReflectDemo {
    public static void main(String[] args){
       try {
           Class c = Class.forName("com.tengj.reflect.Person");
           Method[] methods = c.getDeclaredMethods();
           for(Method m:methods){
               String  methodName= m.getName();
               System.out.println(methodName);
           }
       } catch (Exception e) {
           e.printStackTrace();
       }
    }
}

获取成员变量Field:

  • public Field getDeclaredField(String name) // 获得该类自身声明的所有变量,不包括其父类的变量。
  • public Field getField(String name) // 获得该类自所有的public成员变量,包括其父类变量。
public class ReflectDemo {
    public static void main(String[] args){
        try {
            Class c = Class.forName("Reflect.Person");
            //获取成员变量
            Field field = c.getDeclaredField("msg"); //因为msg变量是private的,所以不能用getField方法
            Object o = c.newInstance();
            field.setAccessible(true);//设置是否允许访问,因为该变量是private的,所以要手动设置允许访问,如果msg是public的就不需要这行了。
            Object msg = field.get(o);
            System.out.println(msg);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  • Field[] fields = c.getDeclaredFields(); // 获得该类自身声明的所有变量,不包括其父类的变量。
  • Field[] fields = c.getFields(); // 获得该类自所有的public成员变量,包括其父类变量。
public class ReflectDemo {
    public static void main(String[] args){
        try {
            Class c = Class.forName("com.tengj.reflect.Person");
            Field[] fields = c.getDeclaredFields();
            for(Field field :fields){
                System.out.println(field.getName());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

还可以通过
Class intes[]=Class.forName("Reflect.Person").getInterfaces();返回继承的接口。
通过Class temp=Class.forName("Reflect.Person").getSuperclass();返回继承的父类。

你可能感兴趣的:(Java反射)