栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java反射和常用操作

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java反射和常用操作

每天进步一点点
  • 一、什么是反射
    • 1.1 类对象
    • 1.2 类的对象
  • 二、获取类对象的三种方法
    • 2.1 Object类中的getClass()方法
    • 2.2 类.class
    • 2.3 通过Class类的forName()方法
  • 三、使用反射进行类的实例化操作
    • 3.1 调用无参构造方法进行实例化
    • 3.2 调用有参构造方法进程实例化
  • 四、反射的常用操作
    • 4.1 使用反射获取类名、包名、父类、接口
    • 4.2 使用反射获取类的属性
    • 4.3 使用反射获取类的构造方法
    • 4.4 使用反射获取类中的方法并调用

一、什么是反射

Java反射机制是在运行状态中,对于任意一个类,都能知道这个类的所有属性和方法;对于任意一个对象,都能够调用他的任意一个方法和属性,这种动态获取的信息以及动态调用对象方法的功能称为反射。
Class类是一切反射根源

Class类表示什么???

很多的人—>可以定义为一个Person类(有姓名、性别、年龄)
很多的车—>可以定义一个Car类(有颜色、车牌,品牌)
很多个类—>可以定义一个Class类(有类名、属性、方法)

1.1 类对象

类加载的产物,封装了一个类中的所有属性(包名、类名、父类、接口、属性、方法、构造方法)

1.2 类的对象

基于某个类new出来的对象,也称实例对象

二、获取类对象的三种方法
  • Object类中的getClass()方法
  • 类.class
  • 通过Class类的forName()方法

创建一个Person类,后面使用

package com.javase.reflection;

public class Person {
    public int type;
    private String name;//私有属性
    int age;//默认属性
    protected String sex;
    public Person() {
        System.out.println("无参构造方法被调用了!!!");
    }//无参构造方法
    //带三个参数的构造方法
    public Person(String name, int age, String sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
        System.out.println("带参构造方法被调用了!!!");
    }
    public void eat(){//无参方法
        System.out.println(this.name+"吃饭!!!");
    }
    public void eat(String food){//一个参数方法
        System.out.println(this.name+"吃"+food);
    }
    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 String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    //重写toString方法
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + ''' +
                ", age=" + age +
                ", sex='" + sex + ''' +
                '}';
    }
}

2.1 Object类中的getClass()方法
public class Test {
    public static void main(String[] args) throws ClassNotFoundException {
        Person person = new Person();
        //第一种方法:Object中的getClass()方法
        Class aClass = person.getClass();
        System.out.println(aClass);
    }
}
2.2 类.class
public class Test {
    public static void main(String[] args) throws ClassNotFoundException {
        //第二中方法:类.class
        Class bClass = Person.class;
        System.out.println(bClass);
    }
}
2.3 通过Class类的forName()方法
public class Test {
    public static void main(String[] args) throws ClassNotFoundException {
        //第三重方法:Class.forName()方法 (推荐使用第三种方式)
        Class cClass = Class.forName("com.javase.reflection.Person");
        System.out.println(cClass);
    }
}

三种方法的结果

三、使用反射进行类的实例化操作 3.1 调用无参构造方法进行实例化
  • public Constructor getConstructor()获取类的无参构造方法
  • public T newInstance()创建对象实例
public class TestCode01 {
    public static void main(String[] args) throws Exception {
        //通过反射实例化对象
        Class aClass = Class.forName("com.javase.reflection.Person");
        //使用newInstance()方法创建实例,调用的是无参构造方法
        Person p1 = (Person) aClass.newInstance();
        //获取无参构造方法
        Constructor con = aClass.getConstructor();
        Person p2 = (Person)con.newInstance();
    }
}

3.2 调用有参构造方法进程实例化

public Constructor getConstructor(类... parameterTypes)获取返回一个Constructor对象,该对象反映Constructor对象表示的类的指定的公共类函数。

public class TestCode01 {
    public static void main(String[] args) throws Exception {
        //通过反射实例化对象
        Class aClass = Class.forName("com.javase.reflection.Person");
        Constructor con = aClass.getConstructor(String.class, int.class, String.class);
        Person p = (Person)con.newInstance("张三", 20, "男");
    }
}

四、反射的常用操作 4.1 使用反射获取类名、包名、父类、接口
  • public String getName()获取类的名字
  • public Package getpackage()获取类的包名
  • public Class getSuperclass()获取类的父类
  • public Class[] getInterfaces()获取类的接口
public class TestCode01 {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        //通过反射实例化对象
        Class aClass = Class.forName("com.javase.reflection.Person");
        //获取类的名字
        String name = aClass.getName();
        System.out.println(name);
        //获取类的包名
        Package aPackage = aClass.getPackage();
        System.out.println(aPackage.toString());
        //获取类的父类
        Class superclass = aClass.getSuperclass();
        System.out.println(superclass.toString());//Object是所有类的父类
        //获取类的接口
        Class[] interfaces = aClass.getInterfaces();//一个类可以继承多个接口,返回的是一个数组
        System.out.println(interfaces.toString());
    }
}

4.2 使用反射获取类的属性
  • getFields()获取运行时类和父类中被public修饰的属性
  • getDeclaredFields()获取运行中的所有属性
  • getField(String name),getDeclarreField(String name)获取指定属性
  • 属性.getType()获取属性的数据类型
  • 属性.getModifiers()获取属性的修饰符
  • 属性.set(Object obj,Object value)给属性赋值
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class TestCode02 {
    public static void main(String[] args) throws Exception {
        Class aClass = Class.forName("com.javase.reflection.Person");
        //获取运行时类和父类中被public修饰的属性
        Field[] fields = aClass.getFields();
        for (Field f : fields) {
            System.out.println(f);
        }
        System.out.println("--------------------");
        //获取运行中的所有属性
        Field[] declaredFields = aClass.getDeclaredFields();
        for(Field f : declaredFields){
            System.out.println(f);
        }
        System.out.println("--------------------");
        //获取指定属性
        Field name = aClass.getDeclaredField("name");
        System.out.println(name);
        System.out.println("--------------------");
        //获取属性的数据类型
        Class type = name.getType();
        System.out.println(type);
        System.out.println("--------------------");
        //获取属性的修饰符
        int modifiers = name.getModifiers();
        System.out.println(modifiers);
        System.out.println(Modifier.toString(name.getModifiers()));
        System.out.println("--------------------");
        //给属性赋值
        Field type1 = aClass.getField("type");
        Person p =(Person) aClass.newInstance();
        type1.set(p,22);
        System.out.println(p.type);
    }
}

4.3 使用反射获取类的构造方法

public Constructor[] getConstructors()获取类的构造方法

public class TestCode01 {
    public static void main(String[] args) throws Exception {
        //通过反射实例化对象
        Class aClass = Class.forName("com.javase.reflection.Person");
        //获取类的构造方法
        Constructor[] constructors = aClass.getConstructors();
        for (Constructor con:constructors){
            System.out.println(con.toString());
        }
    }
}

4.4 使用反射获取类中的方法并调用
  • getMethods()获取public 的方法,包括从父类继承过来的方法
  • getDeclaredMethods()获取类中所有的方法,不包含继承方法
public class TestCode01 {
    public static void main(String[] args) throws Exception {
        //通过反射实例化对象
        Class aClass = Class.forName("com.javase.reflection.Person");
        //获取类中public方法,包括父类继承过来的方法
        Method[] methods = aClass.getMethods();
        for (Method method : methods) {
            System.out.println(method.toString());
        }
        //获取类中所有的方法,包括private修饰的方法
        Method[] declaredMethods = aClass.getDeclaredMethods();
        for (Method method : declaredMethods) {
            System.out.println(method.toString());
        }
    }
}

  • getMethod(String name, 类...parameterTypers)获取单个方法,参数为方法名,参数类型
  • invoke(Object obj,Object... args)在具有指定参数的方法对象上调用此方法对象表示的基础方法
public class TestCode01 {
    public static void main(String[] args) throws Exception {
        //通过反射实例化对象
        Class aClass = Class.forName("com.javase.reflection.Person");
        //获取单个方法,无参方法并调用
        Method eat1 = aClass.getMethod("eat");
        Person p =(Person) aClass.newInstance();//创建对象
        eat1.invoke(p);//==p.eat();
        //获取一个带参的方法
        Method eat2 = aClass.getMethod("eat", String.class);
        eat2.invoke(p,"小龙虾!");
    }
}

  • getDeclaredMethod()可以获取类中的私有方法,但是私有方法不能直接调用,只能在类中调用,如果使用,就要设置它访问权限无效
  • setAccessible(boolean b)设置访问权限无效
public class TestCode01 {
    public static void main(String[] args) throws Exception {
        //通过反射实例化对象
        Class aClass = Class.forName("com.javase.reflection.Person");
        Person p = (Person) aClass.newInstance();
		//获取私有方法
        Method privateMethod = aClass.getDeclaredMethod("privateMethod");
        //设置访问权限无效
        privateMethod.setAccessible(true);
        //调用方法
        privateMethod.invoke(p);
    }
}

获取调用静态方法,使用invoke()方法不需要传入对象–>invoke(null)

public class TestCode01 {
    public static void main(String[] args) throws Exception {
        //通过反射实例化对象
        Class aClass = Class.forName("com.javase.reflection.Person");
		//获取私有方法
        Method staticMethod = aClass.getDeclaredMethod("staticMethod");
        //调用方法
        staticMethod.invoke(null);//==p.staticMethod
    }
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/856460.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号