Java反射(1)---四大核心类及常用操作

反射在java中是非常重要的。反射是学习java框架的灵魂。

什么是反射,来看张图:

简单来说,我们在之前,一般都是在用new来开辟空间,调用对象。也就是说我们通过包名,寻找类方法来进行操作。这样的方法我们可以称之为“正”操作,而反方法我们需要的是逆向思维,去反推。

反射就是根据已有类的对象反推类的组成:
反射操作形式

在反射的世界里,看重的不在是一个对象,而是对象身后的组成。

Class类:描述具体类的信息。Class类对象用JVM产生,当类装载的时候,JVM产生改类的唯一class对象。
class类对象的三种实例化模式:
Class类是描述整个类的概念,也是整个反射的操作源头,在使用Class类的时候需要关注的依然是这个类的对象。而这个类的对象的产生模式一共有三种:

  1. 任何类的实例化对象可以通过Object类中的getClass()方法取得Class类对象。
     Class cls1 = data.getClass();
  1. “类.class”:直接根据某个具体的类来取得Class类的实例化对象。
Class cls2 = Data.class
  1. 使用Class类提供的方法:public static Class
Class cls3 = Class.forName("java.util.Data")

我们用的最多的一般是第三种,在导入数据库的时候第三种方法比较简单。

Construct类:描述类中的构造方法类

两个方法:
1、取得指定参数类型的构造:

public Constructor<T> getConstructor(Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException

2、取得类中的所有构造:

public Constructor<?>[] getConstructors() throws SecurityException

代码实现

package TestClass;

import java.lang.reflect.Constructor;

class Person {
    public Person() {
    }

    public Person(String name) {
    }

    public Person(String name, int age) {
    }
}

public class Class1 {
    public static void main(String[] args) {
        Class<?> class1 = Person.class;
        Constructor<?>[] constructors = class1.getConstructors();
        for (int i = 0; i < constructors.length; i++) {
            Constructor<?> constructor = constructors[i];
            System.out.println(constructor);
        }
    }

}

这里写图片描述

我们可以看出是直接利用了Constructor类中的toString()方法取得了构造方法的完整信息(包含方法权限,参数列表),而如果只使用了getName()方法,只会返回构造方法的包名.类名。

在定义简单JAVA类的时候一定要保留一个无参构造:
Class类通过反射实例化类对象的时候,只能够调用类中的无参构造。如果现在类中没有无参构造则无法使用Class类调用,只能够通过明确的构造调用实例化处理。

Method类:取得类中的普通方法
1、
a.
取得类中的全部方法:

getMethods() :取得本类以及父类中所有权限为public方法的普通方法
getDeclaredMethods():取得本类中的普通方法,无关权限

代码实现:

import java.lang.reflect.Method;

class Person{
    private String name;
    private int age;
    public Person() {}
    public Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }
    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 class Test6 {
    public static void main(String[] args) {
        Class<?> class1 = Person.class;
        Method[] methods = class1.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }
    }

}

b.
取得类中指定参数方法

//根据方法以及参数取得指定普通方法,权限为public
//如果指定名称的方法在本类中没有,会继续在父类中查找
getMethod(String name,Class<?>...parameterTypes)
//只在本类找指定名称,以及参数类型的普通方法,无关权限
getDeclaredMethod(String name,Class<?>...parameterTypes)

c.调用拿到的普通方法

//通过反射调用拿到的Method方法
invoke(Object obj,Object...args)

代码实现:

public class Test6 {
    public static void main(String[] args)
            throws Exception {
        // Class<?> class1 = Person.class;
        // Method[] methods = class1.getMethods();
        // for (Method method : methods) {
        // System.out.println(method);
        // }

        Class<?> cls = Class.forName("TestClass.Person");
        // 任何时候调用类中的普通方法都必须有实例化对象
        Object obj = cls.newInstance();
        // 取得setName这个方法的实例化对象,设置方法名称与参数类型
        Method setMethod = cls.getMethod("setName", String.class);
        // 随后需要通过Method类对象调用指定的方法,调用方法需要有实例化对象
        // 同时传入参数
        setMethod.invoke(obj, "y"); // 相当于Person对象.setName("y") ;
        Method getMethod = cls.getMethod("getName");
        Object result = getMethod.invoke(obj); // 相当于Person对象.getName() ;
        System.out.println(result);
    }

}

Filed类:反射类中的属性
a.取得所有的属性

getFile():取得本类以及父类中所有public权限属性。静态和全局都能看到
getDeclaredMethods():取得本类中的所有属性,只找本类的与权限无关

b.取得指定名称属性

getFile(String name):取得本类以及父类中所有public权限属性。
getDeclared fileString):取得本类中的所有属性

c.取得属性类型

gettype()

d.动态破坏封装性(!!!!需谨慎使用)

//动态破坏封装性,只此一次。在当前的JVM进程中
filed.setAccessible()

代码实现:

import java.text.DateFormat.Field;

class Person {
    public String name;
    public int age;
}


class Student extends Person {
    private String school;
}

public class Test7 {
    public static void main(String[] args) throws Exception {
        Class<?> cls = Class.forName("TestClass.Student");
        { // 普通代码块
            // 第一组-取得类中全部属性
            Field[] fields = cls.getFields();
            for (Field field : fields) {
                System.out.println(field);
            }
        }
        System.out.println("------------------------");
        {
            // 第二组-取得类中全部属性
            Field[] fields = cls.getDeclaredFields();
            for (Field field : fields) {
                System.out.println(field);
            }
        }
    }
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值