45. 创建运行时类的对象-获取运行时类的所有属性及方法的完整结构-调用运行时类的指定属性/方法

创建运行时类的对象

    //创建运行时类的对象
    @Test
    public void test2() throws Exception {
        Class<Car> carClass = Car.class;
        //调用newInstance创建一个运行时类的对象,该方法内部实际上调用了运行时类的空参构造器
        //这里如果把Car类的空参构造器屏蔽掉再运行,就会报NoSuchMethodException的错误;
        //其次空参构造器的访问权限不能是private
        Car obj = carClass.getDeclaredConstructor().newInstance();
        System.out.println(obj);

    }

对反射动态性的一个体会,编译时无法确定创建什么类,运行时才可确定。

    @Test
    public void test3() throws ClassNotFoundException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        int i = new Random().nextInt(3);
        String classPath = "";
        switch (i) {
            case 0:
                classPath = "com.senior.reflect.Car";
                break;
            case 1:
                classPath = "java.lang.Object";
                break;
            case 2:
                classPath = "java.util.Date";
                break;
        }

        Object instance = getInstance(classPath);
        System.out.println(instance);

    }

    //通过反射得到一个类的对象
    public Object getInstance(String classPath) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Class aClass = Class.forName(classPath);
        return aClass.getDeclaredConstructor().newInstance();
    }

可以获取运行时类的所有属性及方法的完整结构

package com.senior.reflect;

import org.junit.Test;

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

/**
 * @author eden
 * @Description
 * @create projectTest-com.senior.reflect:2021-05-14-17:44
 * @since
 */
public class RunTimeClassTest {

    //获取运行时类的所有属性
    @Test
    public void test() throws ClassNotFoundException {
        Class<?> clazz = Class.forName("com.senior.reflect.Person");

        //getFields()获取当前运行时类及其父类声明为public的属性
//        Field[] fields = clazz.getFields();
//        for(Field f:fields)
//        {
//            System.out.println(f);
//        }

        //getDeclaredFields()获取当前运行时类(不包含父类)的所有属性,不分权限
        Field[] fields1 = clazz.getDeclaredFields();
        for(Field f:fields1)
        {
            System.out.println(f);
            //1.权限修饰符
            int modifiers = f.getModifiers();//具体数字表示什么可以看Modifier类
            System.out.print(Modifier.toString(modifiers)+"\t");
            //2.数据类型
            Class type = f.getType();
            System.out.print(type.getName()+"\t");
            //3.变量名
            String name = f.getName();
            System.out.print(name+"\t");

            System.out.println();
        }


    }

    //获取运行时类的方法结构
    @Test
    public void test1() throws ClassNotFoundException {
        Class aClass = Class.forName("com.senior.reflect.Person");
        //getMethods()获取当前运行时类及其父类声明为public的方法
//        Method[] methods = aClass.getMethods();
//        for(Method m:methods)
//        {
//            System.out.println(m);
//        }

        //getDeclaredFields()获取当前运行时类(不包含父类)的所有方法,不分权限
        Method[] declaredMethods = aClass.getDeclaredMethods();
        for(Method f:declaredMethods){
            System.out.println(f);
        }
        //可以获取运行时类的方法的各种结构,包括参数 返回值等等,这里不赘述
    }
}

//Creature父类
public class Creature<T> implements Serializable {
    private char gender;
    public double weight;

    private void breath()
    {
        System.out.println("呼吸");
    }
     public void eat(){
         System.out.println("吃东西");
     }

}

public class Person extends Creature<String> implements Serializable, Comparable<String> {
    public String name;
    private int age;

    public Person() {
    }

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

    private String showNation(String nation) {
        System.out.println("我的国籍是:" + nation);
        return nation;
    }

    public void show() {
        System.out.println("Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}');
    }

    @Override
    public int compareTo(String o) {
        return o.compareTo(this.name);
    }

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

还可以获取构造器,获取方法抛出的异常,获取运行时类所在的接口,包,注解等等,这里不赘述,用到再说。


调用运行时类的指定属性/方法

public class RunTimeClassTest2 {
    //操作运行时类的指定属性
    @Test
    public void testField() throws Exception {
        //获取运行时类
        Class<Person> clazz = (Class<Person>) Class.forName("com.senior.reflect.Person");

        //创建运行时类的对象
        Person person = clazz.getDeclaredConstructor().newInstance();
        //获取指定的属性
        Field name = clazz.getField("name");
        name.set(person,"XDD");//设置当前属性值
        System.out.println(person);

        Field age = clazz.getDeclaredField("age");
        age.setAccessible(true);//setAccessible为true,则可设置缺省权限和private权限的成员变量
        age.set(person,30);//设置当前属性值
        System.out.println(person);



    }

    //操作运行时类的指定方法
    @Test
    public void testMethod() throws Exception {
        Class<Person> clazz = (Class<Person>) Class.forName("com.senior.reflect.Person");

        Person person = clazz.getDeclaredConstructor().newInstance();
        //调用类的私有方法
        Method showNation = clazz.getDeclaredMethod("showNation", String.class);
        showNation.setAccessible(true);
        Object nation = showNation.invoke(person, "China");
        System.out.println(nation.toString());

        System.out.println("-------------如何调用静态方法-----------------");
        Method show = clazz.getDeclaredMethod("show");
        Object obj = show.invoke(person);
//        Object obj = show.invoke(null);//也可

    }
}

一般很少通过这种方式调用指定的构造器,操作流程与上述类似,不赘述。

该博客图片来源于尚硅谷宋老师教学课件

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 您可以使用 `**kwargs` 参数来获取所有未命名的关键字参数,然后将其作为字典来处理。例如,假设您有一个包含许多属性对象 `my_object`,您可以使用以下代码来获取所有属性: ``` def get_all_properties(**kwargs): return kwargs all_properties = get_all_properties(**my_object.__dict__) ``` 这将返回一个字典,其中包含所有属性的键值对。在这个例子中,`my_object.__dict__` 返回一个包含对象所有属性的字典,然后将这个字典作为参数传递给 `get_all_properties` 函数。 `**kwargs` 参数将接收到这个字典,并将其作为未命名的关键字参数来处理。最终,`get_all_properties` 函数将返回一个包含所有属性的字典。 ### 回答2: 如果MT(机器翻译)的属性太多,不想在括号里逐一获取,可以考虑以下几种方法。 1. 使用循环结构:通过编写循环来遍历MT的属性,以便一次性获取所有属性的值。可以使用for循环或while循环,依次访问每个属性并将其保存在一个集合中(如列表、字典等)。 2. 使用通用方法:某些编程语言或框架提供了通用的方法获取对象属性。可以通过查阅相应文档,寻找能够获取MT所有属性方法。这样就不需要逐一指定每个属性。 3. 使用反射机制:反射是一种能够在运行时动态获取对象属性方法的机制。通过使用反射,可以获取MT的属性列表,并根据需要提取属性的值。反射的具体实现方式因编程语言而异,可以查阅相关文档了解如何使用反射机制。 4. 封装属性访问方法:可以编写一个方法或函数,用于一次性获取MT的所有属性。该方法可以使用上述方法之一来实现,然后将属性的值返回给调用者。这样,在其他地方使用MT对象时,只需要调用这个方法,而不需要逐个获取属性。 需要注意的是,以上方法的可行性和具体实现方式会受限于所使用的编程语言和MT的具体实现。在实际应用时,可以根据情况选择最适合的方法。 ### 回答3: 如果MT的属性太多,不想在括号里面逐一获取,我们可以考虑使用循环结构来简化代码。首先,我们可以将MT的属性存储在一个字典或列表中,以便更方便地进行处理。然后,使用循环遍历这个字典或列表,针对每个属性进行相应的操作。 例如,假设MT的属性存储在一个名为“attributes”的字典中,我们可以使用如下步骤处理这些属性: 1. 创建一个空的结果列表,用于存储获取到的属性值。 2. 使用循环遍历字典中的每个属性。 3. 针对每个属性,通过字典的键来获取其对应的值,并将该值添加到结果列表中。 4. 循环结束后,我们可以得到一个包含所有属性值的结果列表。 下面是一个示例代码: ``` attributes = {"属性1": 值1, "属性2": 值2, "属性3": 值3, ...} results = [] for attribute in attributes.values(): results.append(attribute) print(results) ``` 通过这样的方式,我们可以避免在括号里逐一获取每个属性,而是通过循环结构来自动处理所有属性,从而简化代码的编写和维护。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值