初级程序员必会的java反射教程

目录

 1. 创建一个Person实体类

2. 反射获取Class类对象的三种方法

2.1 通过全类名的方式获取

2.2 类名.class

 2.3 实例对象.getClass() 

2.4 总结

  3. 反射获取属性变量

3.1 获取所有public修饰符的成员变量

3.2 获取指定字段并赋值

  3.3 获取所有的成员变量(不考虑修饰符)

 3.4 获取私有的变量(利用暴力反射)

4.反射获取构造方法

  4.1有参构造

4.2无参构造

  4.3无参构造简便写法

5.反射获取成员方法

  5.1无参方法     

  5.2 有参方法

  5.3 获取所有方法(包含Object的方法)

项目源码下载地址 : https://download.csdn.net/download/qq_45481709/86708493


 1. 创建一个Person实体类

在后续的反射演示中我们都会拿Person类中的类名, 属性, 方法做演示

package com.learning.java.fanshe.domain;


import lombok.Data;

/**
 * 拓展 :
 * 1.构造器必须与类同名(如果一个源文件中有多个类,那么构造器必须与公共类同名)
 * 2.每个类可以有一个以上的构造器
 * 3.构造器可以有0个、1个或1个以上的参数
 * 4.构造器没有返回值
 * 5.构造器总是伴随着new操作一起调用
 */
@Data
public class Person {
    private String name;
    private Integer age;

    public String sex;

    public Person() {
    }
    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public void walk() {
        System.out.println("我在走路");
    }
    public void walk(String name) {
        System.out.println(name + "在走路");
    }
    private void a() {

    }


}

2. 反射获取Class类对象的三种方法

2.1 通过全类名的方式获取

Class a = Class.forName("com.learning.java.fanshe.domain.Person");
System.out.println(a);

首先这里的全类名可以理解为类的包路径

初级程序员必会的java反射教程_第1张图片

Class.forName的作用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段
输出结果 : 
class com.learning.java.fanshe.domain.Person

2.2 类名.class

Class b = Person.class;
System.out.println(b);

用Class.类名的方法, jvm把类加载进内存但不进行初始化,返回Class对象

输出结果 : 
class com.learning.java.fanshe.domain.Person

 2.3 实例对象.getClass() 

Class c = new Person().getClass();
System.out.println(c);

对类进行静态初始化、非静态初始化,返回引用是运行时真正所指对象(向上转型)所属类的Class对象

输出结果 : 
class com.learning.java.fanshe.domain.Person

2.4 总结

在完成上面三种获取class类对象后, 不难发现最后输出的结果是一样的, 这里我们再用代码证实一下

    public static void main(String[] args) throws Exception {
        Class a = Class.forName("com.learning.java.fanshe.domain.Person");
        System.out.println(a);

        Class b = Person.class;
        System.out.println(b);

        Class c = new Person().getClass();
        System.out.println(c);
        
        System.out.println(a == b);
        System.out.println(b == c);
        
    }
输出结果 : 
true
true

结论:

同一个字节码文件(*,c1ass)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的class对象都是同一个

  3. 反射获取属性变量

3.1 获取所有public修饰符的成员变量

Class persionClass = Person.class;
 Field[] fields = persionClass.getFields();
        for (Field field : fields) {
            //注: 这里只能获取public修饰的变量
            System.out.println(field);
        }
输出结果:
public java.lang.String com.learning.java.fanshe.domain.Person.sex

3.2 获取指定字段并赋值

Field sex = persionClass.getField("sex");
        //获取成员变量sex的值
        Person person = new Person();
        //设置a的值
        sex.set(person, "张安");
        Object o = sex.get(person);
        System.out.println(o);
输出结果: 
张安

  3.3 获取所有的成员变量(不考虑修饰符)

  for (Field declaredField : persionClass.getDeclaredFields()) {
            System.out.println(declaredField);
        }
输出结果:
private java.lang.String com.learning.java.fanshe.domain.Person.name
private java.lang.Integer com.learning.java.fanshe.domain.Person.age
public java.lang.String com.learning.java.fanshe.domain.Person.sex

 3.4 获取私有的变量(利用暴力反射)

之前我们的属性name是私有属性 private String name 如果想获取就需要暴力setAccessible(true)

 //获取私有的变量
        Field name = persionClass.getDeclaredField("name");
        //忽略访问权限修饰符的安全检查(暴力反射)
        name.setAccessible(true);
        Object o1 = name.get(person);
        System.out.println(o1);

 这里因为并未给该变量赋值所以输出为null

输出结果:
null


4.反射获取构造方法

  4.1有参构造

        //创建有参
        Constructor constructor = persionClass.getConstructor(String.class, Integer.class);
        System.out.println(constructor);
        //创建对象
        Person person1 = constructor.newInstance("张三", 12);
        System.out.println(person1);
输出结果:
public com.learning.java.fanshe.domain.Person(java.lang.String,java.lang.Integer)
Person(name=张三, age=12, sex=null)

4.2无参构造

 //创建无参构造
        Constructor constructor1 = persionClass.getConstructor();
        System.out.println(constructor1);
        //创建对象
        Person person2 = constructor1.newInstance();
        System.out.println(person2);
输出结果:
public com.learning.java.fanshe.domain.Person()
Person(name=null, age=null, sex=null)

  4.3无参构造简便写法

 //无参构造的简便写法
        Person person3 = persionClass.newInstance();
        System.out.println(person3);
输出结果:
Person(name=null, age=null, sex=null)

5.反射获取成员方法

  5.1无参方法     

Method walk = persionClass.getMethod("walk");
        Person person4 = new Person();
        //执行方法
        walk.invoke(person4);
输出结果:
我在走路

  5.2 有参方法

Method walk1 = persionClass.getMethod("walk", String.class);
        walk1.invoke(person4,"张三");
输出结果:
张三在走路

  5.3 获取所有方法(包含Object的方法)

Method[] methods = persionClass.getMethods();
        for (Method method : methods) {
            method.setAccessible(true);
            //获取方法名称
            System.out.println(method.getName());
            System.out.println(method);
        }
equals
public boolean com.learning.java.fanshe.domain.Person.equals(java.lang.Object)
toString
public java.lang.String com.learning.java.fanshe.domain.Person.toString()
hashCode
public int com.learning.java.fanshe.domain.Person.hashCode()
getName
public java.lang.String com.learning.java.fanshe.domain.Person.getName()
setName
public void com.learning.java.fanshe.domain.Person.setName(java.lang.String)
walk
public void com.learning.java.fanshe.domain.Person.walk()
walk
public void com.learning.java.fanshe.domain.Person.walk(java.lang.String)
getAge
public java.lang.Integer com.learning.java.fanshe.domain.Person.getAge()
setAge
public void com.learning.java.fanshe.domain.Person.setAge(java.lang.Integer)
setSex
public void com.learning.java.fanshe.domain.Person.setSex(java.lang.String)
getSex
public java.lang.String com.learning.java.fanshe.domain.Person.getSex()
wait
public final void java.lang.Object.wait() throws java.lang.InterruptedException
wait
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
wait
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
getClass
public final native java.lang.Class java.lang.Object.getClass()
notify
public final native void java.lang.Object.notify()
notifyAll
public final native void java.lang.Object.notifyAll()
我在走路

你可能感兴趣的:(Java,jvm,java,反射)