java、反射

1 类的加载

类加载的描述:

        当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过类的加载,类的连接,类的初始化这三个步骤来对类进行初始化。如果不出现意外情况,JVM将会连续完成这三个步骤,所以有时也把这三个步骤统称为类加载或者类初始化

类的加载:

        就是指将class文件读入内存,并为之创建一个 java.lang.Class 对象

        任何类被使用时,系统都会为之建立一个 java.lang.Class 对象

类的连接:

        验证阶段:用于检验被加载的类是否有正确的内部结构,并和其他类协调一致

        准备阶段:负责为类的类变量分配内存,并设置默认初始化值

        解析阶段:将类的二进制数据中的符号引用替换为直接引用

类的初始化:

        在该阶段,主要就是对类变量进行初始化

 

 

1.2类加载器

类加载器的作用:

        负责将.class文件加载到内存中,并为之生成对应的 java.lang.Class 对象。虽然我们不用过分关心类加载机制,但是了解这个机制我们就能更好的理解程序的运行!

Java中的内置类加载器:

        Bootstrap class loader:它是虚拟机的内置类加载器,通常表示为null ,并且没有父null

        Platform class loader:平台类加载器可以看到所有平台类 ,平台类包括由平台类加载器或其祖先定义的Java SE平台API,其实现类和JDK特定的运行时类

        System class loader:它也被称为应用程序类加载器 ,与平台类加载器不同。 系统类加载器通常用于定义应用程序类路径,模块路径和JDK特定工具上的类

        类加载器的继承关系:System的父加载器为Platform,而Platform的父加载器为Bootstrap

1.3  ClassLoader 中的两个方法

static ClassLoader getSystemClassLoader()         返回用于委派的系统类加载器

ClassLoader getParent()                                        返回父类加载器进行委派

2 反射

2.1 三种分类方式

类名.class属性

对象名.getClass()方法

Class.forName(全类名)方法

public static void main(String[] args) throws ClassNotFoundException {
        //使用类的class属性来获取该类对应的Class对象
        Class<Student> c1 = Student.class;
        System.out.println(c1);

        Class<Student> c2 = Student.class;
        System.out.println(c1 == c2);
        System.out.println("--------");

        //调用对象的getClass()方法,返回该对象所属类对应的Class对象
        Student s = new Student();
        Class<? extends Student> c3 = s.getClass();
        System.out.println(c1 == c3);
        System.out.println("--------");

        //使用Class类中的静态方法forName(String className)
        Class<?> c4 = Class.forName("com.itheima_02.Student");
        System.out.println(c1 == c4);
    }

2.2 Class类获取构造方法对象的方法

Constructor<?>[] getConstructors()         返回所有公共构造方法对象的数组

Constructor<?>[] getDeclaredConstructors()         返回所有构造方法对象的数组

Constructor<T> getConstructor(Class<?>... parameterTypes) 返回单个公共构造方法对象

Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 返回单个构造方法对象

Constructor类用于创建对象的方法

T newInstance(Object...initargs)         根据指定的构造方法创建对象

例子:

public class Student {  //创建一个学生类
    //成员变量:一个私有,一个默认,一个公共
    private String name;
    int age;
    public String address;

    //构造方法:一个私有,一个默认,两个公共
    public Student() {
    }

    private Student(String name) {
        this.name = name;
    }

    Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Student(String name, int age, String address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }

    //成员方法:一个私有,四个公共
    private void function() {
        System.out.println("function");
    }

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

    public void method2(String s) {
        System.out.println("method:" + s);
    }

    public String method3(String s, int i) {
        return s + "," + i;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", address='" + address + '\'' +
                '}';
    }
}

public class ReflectDemo02 { //测试类
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //获取Class对象
        Class<?> c = Class.forName("com.itheima_02.Student");

        //public Student(String name, int age, String address)
        //Constructor<T> getConstructor(Class<?>... parameterTypes)
        Constructor<?> con = c.getConstructor(String.class, int.class, String.class);
        //基本数据类型也可以通过.class得到对应的Class类型

        //T newInstance(Object... initargs)
        Object obj = con.newInstance("林青霞", 30, "西安");
        System.out.println(obj);
    }
}

public class ReflectDemo03 { //测试类
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //获取Class对象
        Class<?> c = Class.forName("com.itheima_02.Student");

        //private Student(String name)
        //Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
        Constructor<?> con = c.getDeclaredConstructor(String.class);

        //暴力反射
        //public void setAccessible(boolean flag):值为true,取消访问检查
        con.setAccessible(true);

        Object obj = con.newInstance("林青霞");
        System.out.println(obj);
    }
}

2.3 Class获取成员变量对象的方法

Field[] getFields()                       返回所有公共成员变量对象的数组

Field[] getDeclaredFields()         返回所有成员变量对象的数组

Field getField(String name)        返回单个公共成员变量对象

Field getDeclaredField(String name)         返回单个成员变量对象

Field类用于给成员变量赋值的方法

voidset(Object obj,Object value)                 给obj对象的成员变量赋值为value

例子:

public class ReflectDemo02 {
    public static void main(String[] args) throws Exception {
        //获取Class对象
        Class<?> c = Class.forName("com.itheima_02.Student");

        //Student s = new Student();
        Constructor<?> con = c.getConstructor();
        Object obj = con.newInstance();
        System.out.println(obj);

        //s.name = "林青霞";
//        Field nameField = c.getField("name"); //NoSuchFieldException: name
        Field nameField = c.getDeclaredField("name");
        nameField.setAccessible(true);
        nameField.set(obj, "林青霞");
        System.out.println(obj);

        //s.age = 30;
        Field ageField = c.getDeclaredField("age");
        ageField.setAccessible(true);
        ageField.set(obj,30);
        System.out.println(obj);

        //s.address = "西安";
        Field addressField = c.getDeclaredField("address");
        addressField.setAccessible(true);
        addressField.set(obj,"西安");
        System.out.println(obj);
    }
}

2.4Class获取成员方法对象的方法

Method[] getMethods()                 返回所有公共成员方法对象的数组,包括继承的

Method[] getDeclaredMethods()                 返回所有成员方法对象的数组,不包括继承的

Method getMethod(String name, Class<?>... parameterTypes) 返回单个公共成员方法对象

Method getDeclaredMethod(String name, Class<?>... parameterTypes) 返回单个成员方法对象

Method类用于执行方法的方法:

Objectinvoke(Object obj,Object... args) 调用obj对象的成员方法,参数是args,返回值是Object类型

例子:

public class ReflectDemo01 {
    public static void main(String[] args) throws Exception {
        //获取Class对象
        Class<?> c = Class.forName("com.itheima_02.Student");

        //Method[] getMethods() 返回一个包含 方法对象的数组, 方法对象反映由该 Class对象表示的类或接口的所有公共方法,包括由类或接口声明的对象以及从超类和超级接口继承的类
        //Method[] getDeclaredMethods() 返回一个包含 方法对象的数组, 方法对象反映由 Class对象表示的类或接口的所有声明方法,包括public,protected,default(package)访问和私有方法,但不包括继承方法
//        Method[] methods = c.getMethods();
        Method[] methods = c.getDeclaredMethods();
        for(Method method : methods) {
            System.out.println(method);
        }
        System.out.println("--------");

        //Method getMethod(String name, Class<?>... parameterTypes) 返回一个 方法对象,该对象反映由该 Class对象表示的类或接口的指定公共成员方法
        //Method getDeclaredMethod(String name, Class<?>... parameterTypes) 返回一个 方法对象,它反映此表示的类或接口的指定声明的方法 Class对象
        //public void method1()
        Method m = c.getMethod("method1");

        //获取无参构造方法创建对象
        Constructor<?> con = c.getConstructor();
        Object obj = con.newInstance();

//        obj.m();

        //在类或接口上提供有关单一方法的信息和访问权限
        //Object invoke(Object obj, Object... args) 在具有指定参数的指定对象上调用此 方法对象表示的基础方法
        //Object:返回值类型
        //obj:调用方法的对象
        //args:方法需要的参数
        m.invoke(obj);

//        Student s = new Student();
//        s.method1();
    }
}

小练习:

        通过反射获取成员方法并调用

        通过反射技术,向一个泛型为Integer的集合中添加一些字符串数据        

        通过反射运行配置文件中指定类的指定方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值