java的反射机制

什么是反射?

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

通过反射来了解类

1、类由属性,方法,构造函数等组成
2、给定一个类或对象,通过反射机制可以动态的了解类的属性方法,构造函数,创建对象,调用方法,改写属性
3、应用场景:(1)运行时,动态的情况下应对外面传入的“类名”,对象实例等。(2)只知道类名字符串。(3)通常应用到框架中 。

常用的反射操作 (以Dog这个类为例子)
package learnReflect;

public class Dog {
    public String name;
    public int age;
    private String owner;
    public  Dog(){
        
    }
    public Dog(String name,int age){
        this.name = name;
        this.age = age;
    }
    public void bark(){
        System.out.println("汪汪");
    }
    public void celebrateBirthday(){
        System.out.println(name+"生日快乐");
        addAge();
    }
    private void addAge(){
        age = age+1;
    }
}

1、通过一个对象获得完整的包名和类名

public static void getClassFullName(Dog d){
        System.out.println("1.获取包名和类名");
        Class c = d.getClass();
        System.out.println("类名: "+c.getName());
        System.out.println("包名: "+c.getPackage().getName());
    }

2、获得Class对象 3种方法

public static void getClassInstance(){
        System.out.println("2.获得类实例 - 2种方法");
        try {
            String className = "learnReflect.Dog";
            Class c = Class.forName(className);
            System.out.println("method 1:"+c.getName());
            
            Class d = Dog.class;
            System.out.println("method 2:"+c.getName());
            
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

3、了解类的各种信息

1、获取本类的声明方法,调用类的方法。

public static void getClassMethod(){
Class dogClazz = Dog.class;
Method[] methods = dogClazz.getMethods();//能获取Dog类所有的public方法,不能获取private
Method[] methods2 = dogClazz.getDeclaredMethods();//只能获取Dog类自己定义的所有方法包括私有方法
for(Method m : methods)
System.out.println(m.getName());
try {
//"bark"是方法名,不存在时会抛出异常,new Class[]{}是参数类型数组,无参数就为空
Method method = dogClazz.getMethod("bark", new Class[]{});
//invoke方法用于调用方法,参数为类的实例和方法的参数
method.invoke(dogClazz.newInstance());
} catch (Exception e) {
e.printStackTrace();
}
}

>2、获得父类信息
>```
public static void getClassSuperClassInfo(){
        Class dogClazz = Dog.class;
        System.out.println("Dog父类的名字是:"+dogClazz.getSuperclass());
    }

3、获得接口信息

public static void getClassInterfaceInfo(){
Class dogClazz = Dog.class;
for(int i = 0; i< dogClazz.getInterfaces().length;i++)
System.out.println(dogClazz.getInterfaces()[i].getName());
}

    
4、根据Class对象创建instance实例 

public static void getInstance(){
System.out.println("创建对象实例======");
Class dogClazz = Dog.class;
try {//方法1:无参的构造方法
Object o = dogClazz.newInstance();
System.out.println("创建的对象是:"+o);
//方法2:有参数的构造方法
Constructor c = dogClazz.getConstructor(new Class[]{String.class,int.class});
Dog o2 = (Dog) c.newInstance("大黄",4);
System.out.println("创建的对象是:"+o2.name);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}

5、操作成员变量

public static void changeFiled(){
System.out.println("改变成员变量======");
Class dogClazz = Dog.class;
try {
Object o = dogClazz.newInstance();
//方法2
Constructor c = dogClazz.getConstructor(new Class[]{String.class,int.class});
Dog o2 = (Dog) c.newInstance("大黄",4);
Field[] fields = dogClazz.getFields();
for(Field f : fields){
System.out.println(f.getName());
}
Field[] fields2 = dogClazz.getDeclaredFields();
for(Field f : fields2){
System.out.println(f.getName());
}
Field f = dogClazz.getField("name");
f.set(o2, "大黑");
System.out.println(f.get(o2));
// getDeclaredField()用于获取私有成员变量,必须设置setAccessible(true)才能改变
Field f2 = dogClazz.getDeclaredField("owner");
f2.setAccessible(true);
f2.set(o2, "张三");
System.out.println(f2.get(o2));
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

你可能感兴趣的:(java的反射机制)