Java反射,类的引用与方法学习笔记

一.类的加载:

  1. 在jvm虚拟机在运行时,会直接去加载main函数。

  1. 当类中存在继承关系时,子类调用静态常量,只会加载mian,父类子类并不会去进行加载。

详情代码如下:

package FanShe;
public class Test06 {

    static {
        System.out.println("main类被加载!");
    }

    public static void main(String[] args) throws ClassNotFoundException {
        //主动引用
//        Son son = new Son();
        //反射也会产生主动引用
//        Class.forName("FanShe.Son");
        //不会产生类引用的方法
        System.out.println(Son.b);//不会加载子类
        //常量不会让父类与子类进行加载
//        System.out.println(Son.M);//只有main类被加载,因为常量在链接阶段就已经存入到调用类的常量池中了。



    }
}
class Father{

    static int b = 2;

    static {
        System.out.println("父类被加载!");

    }

}
class Son extends Father{

    static {
        System.out.println("子类被加载!");
        m=300;
    }
    static int m = 100;
    static final int M = 1;
}

运行结果:

总结:

  1. 只有在new对象的过程中,或者在反射的过程中,才会产生主动引用,让类进行初始化。

  1. 调用常量时,类不会进行加载,因为在链接阶段时查那个良就已经存入到调用类的常量池中了。

  1. 子类调用父类常量时,父类会被加载,但是子类不会被加载。

  1. 类的主动引用一定产生类的初始化,类的被动引用不会产生类的初始化。

  1. jvm虚拟机启动时就回去加载main函数。

二.反射的应用方法:

当我们获取类的class对象后,可以通过Class类的方法来获取User(举例)类中的数据,详情可参考jdk手册(Class)。

package FanShe;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Test07 {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, NoSuchMethodException {
        Class<?> c1 = Class.forName("FanShe.User");

//获得类的名字
        System.out.println(c1.getName());//获取c1包名+类名
        System.out.println(c1.getSimpleName());//获取c1类名

//获得类的对象
        System.out.println("-------------------------------------------------------------------------------------------");
        Object o = c1.newInstance();// c1.newInstance()获取User对象
        System.out.println(o);

//获得类的属性
        System.out.println("-------------------------------------------------------------------------------------------");
        Field[] fields = c1.getFields();//只能够获取User类的public属性
        for (Field field : fields) {
            System.out.println(field);
        }
        System.out.println("-------------------------------------------------------------------------------------------");
        Field[] declaredFields = c1.getDeclaredFields();//获取User类的所有属性
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);
        }
        System.out.println("-------------------------------------------------------------------------------------------");
        Field name = c1.getDeclaredField("name");//获取User类的指定属性,这里的方法没有s
        System.out.println(name);

//获得类的方法
        System.out.println("-------------------------------------------------------------------------------------------");
        Method[] methods = c1.getMethods();//获取本类及其父类的全部方法
        for (Method method : methods) {
            System.out.println("正常的:"+method);
        }
        System.out.println("-------------------------------------------------------------------------------------------");
        Method[] declaredMethods = c1.getDeclaredMethods();//获得本类的方法
        for (Method declaredMethod : declaredMethods) {
            System.out.println("本类的:"+declaredMethod);
        }

        //**为什么获取本类方法的时候会需要参数,原因就是因为方法重载(方法名一致但参数不同),通过参数来区分。
        System.out.println("-------------------------------------------------------------------------------------------");
        Method name1 = c1.getDeclaredMethod("getName",null);//获取本类的指定方法
        Method setName = c1.getDeclaredMethod("setName", String.class);
        System.out.println(name1);
        System.out.println(setName);

//获得类的构造器
        System.out.println("-------------------------------------------------------------------------------------------");
        Constructor<?>[] constructors = c1.getConstructors();//获得所有构造方法
        for (Constructor<?> constructor : constructors) {
            System.out.println("公共构造:"+constructor);
        }
        System.out.println("-------------------------------------------------------------------------------------------");
        Constructor<?>[] declaredConstructors = c1.getDeclaredConstructors();//获得本类构造方法
        for (Constructor<?> declaredConstructor : declaredConstructors) {
            System.out.println("本类构造:"+declaredConstructor);
        }
        System.out.println("-------------------------------------------------------------------------------------------");
        Constructor<?> declaredConstructor = c1.getDeclaredConstructor(String.class,String.class);//获得本类指定构造方法
        System.out.println("指定构造:"+declaredConstructor);
    }
}
//13

运行结果:

  1. 获取类的名称:(包名+类名,类名) 方法:getName() , getSimpleName()

  1. 获取类的对象: 方法:newInstance()

  1. 获取类的属性: 方法:getFields() , getDeclareFields() , getDeclareField()

  1. 获取类的方法: 方法:getMethods() , getDeclareMethods() ,

获取类的指定方法: 方法:getDeclareMethod()

  1. 获取类的构造器: 方法:getConstructors() , getDeclaredConstructors() , getDeclaredConstructor()

小白学习笔记,可能存在错误,希望大佬指点!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值