Java反射(二):

类的加载:

1.加载

2.链接:

​ 验证:确保加载的类信息符合JVM规范

​ 准备:正式为类变量(static)分配内存并设置类变量默认初始值的阶段,这些内存将都在方法去中进行分配

​ 解析:虚拟机常量池内的符号引用(常量名)替换为直接引用(地址)的过程

3.初始化

​ 执行类构造器()方法的过程。(类构造器是构造类信息的,不是构造该类对象的构造器)

​ 虚拟机会保证一个类的()方法在多线程环境中被正确加锁和同步

import java.lang.annotation.ElementType;
import java.util.Objects;

public class Test04 {
    public static void main(String[] args) {
        A a = new A();
        System.out.println(A.m);
    }
}

    /*
    1.先加载到内存(方法区),会产生一个类对应的Class对象(在堆中)
    2.链接,链接结束后 m = 0
    3.初始化
        <clinit>(){
            System.out.println("静态代码")
            m = 300
            m = 100
        }
     */
class A{
    static{
        System.out.println("静态代码块类加载");
        m = 300;
    }

    static int m = 100;

    public A(){
        System.out.println("构造器调用");
    }
}

类加载器

public class Test05 {
    public static void main(String[] args) throws ClassNotFoundException{
        ClassLoader classLoader = Class.forName("Test05").getClassLoader();
        System.out.println(classLoader);
        //JDK内置类的加载
        classLoader = Class.forName("java.lang.Object").getClassLoader();
        System.out.println(classLoader);
        //获得系统类的path
        System.out.println(System.getProperty("java.class.path"));
        //双亲委派机制,为了安全性,先会搜索这个类是否在已有包中存在
        }
    }

获取类运行时的结构

import com.sun.xml.internal.ws.encoding.MtomCodec;

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

public class Test06 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
        Class c1 = Class.forName("User");

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

        //获得类的属性
        System.out.println("====================");
        Field[] fields = c1.getFields();//只能找到Public属性

        fields = c1.getDeclaredFields();//找到全部的属性
        for(Field field : fields){
            System.out.println(field);
        }

        //获得指定属性的值
        Field name = c1.getDeclaredField("name");
        System.out.println(name);

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

        //获得指定方法
        Method getName = c1.getMethod("getName",null);
        Method setName = c1.getMethod("setName", String.class);
        System.out.println(getName);
        System.out.println(setName);

        //获得指定的构造器
        System.out.println("================================");
        Constructor[] constructors = c1.getConstructors();
        for(Constructor constructor : constructors){
            System.out.println(constructor);
        }
        constructors = c1.getDeclaredConstructors();
        for(Constructor constructor : constructors){
            System.out.println(constructor);
        }

        //获得指定的构造器
        Constructor constructor =  c1.getConstructor(String.class,int.class,int.class);
        System.out.println(constructor);
    }

}

class User{
    private String name;
    private int age;
    private int id;

    public User(){

    }

    public User(String name, int age, int id) {
        this.name = name;
        this.age = age;
        this.id = id;
    }

  ............//getter and setter
}

动态创建对象执行方法

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

//动态的创建对象,通过反射
public class Test09 {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
        //获取Class对象
        Class c1 = Class.forName("User");

        //构造一个对象
        User user = (User) c1.newInstance();//本质上是调用了类的无参构造器
        System.out.println(user);//若无无参构造器会报错

        //通过构造器创建对象
        Constructor constructor = c1.getDeclaredConstructor(String.class,int.class,int.class);
        User user1 = (User)constructor.newInstance("aaa",18,20);
        System.out.println(user1);

        //通过反射调用普通方法
        User user3 = (User)c1.newInstance();
        //通过反射获取一个方法
        Method setName = c1.getMethod("setName", String.class);
        //invoke:激活的意思
        //(对象,”方法的值“)
        setName.invoke(user3,"haha");
        System.out.println(user3.getName());

        //通过反射操作属性
        User user4 = (User)c1.newInstance();
        Field name = c1.getDeclaredField("name");
        //直接访问会报错,因为name为private
        //可以关掉一个权限检测,true为取消检测,通过属性方法的setAccessible
        name.setAccessible(true);
        name.set(user4,"kkkkk");
        System.out.println(user4.getName());
    }
}
class User{
    private String name;
    private int age;
    private int id;

    public User(){

    }

    public User(String name, int age, int id) {
        this.name = name;
        this.age = age;
        this.id = id;
    }

    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 int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值