Android 枚举与反射

Android 枚举与反射

一、知识积累
1、反射

(1)反射机制
加载完类之后,会产生一个Class类型的对象,可通过此对象看到类的结构,这就是反射,反射机制允许程序在执行期间使用ReflectionAPI取得类的内部消息,并能够直接操作对象的内部属性及方法。
(2)常用方法

方法名作用
forName(String name)根据name获取Class对象(ps:name为类的全类名)
class.getName()获取Class对象表示的实体名称
getFields()/getField(String name)获取所有公开的成员变量(ps:包括继承变量)/根据name获取Class对象的成员变量(ps:包括继承变量)
getDeclaredFields()/getDeclaredField(String name)获取Class对象定义的成员变量(ps:包括 私有成员变量)/根据name获取Class对象的成员变量
getMethods()/getDeclaredMethods()获取Class对象所有可见方法(ps:包括继承方法)/获取Class对象定义的方法(ps:包括私有,不包括继承方法)
getMethod(String methodfName, parameter list)/getDeclaredMethod(String methodName, parameter list)根据方法名和参数类型列表获取到Class对象对应的方法(ps:包括继承)/根据方法名和参数类型列表获取到Class对象对应的方法(包括私有,不包括继承方法)
class.newInstance()/clazz.newInstance()通过无参和有参构造对象
2、枚举

(1)枚举
枚举是一组有限的常量集合。
(2)常用方法

方法名作用
name()返回当前对象名
ordinal()返回当前对象的索引
values()返回枚举类中的所有常量对象
valueOf(String name)根据name转换成已存在的枚举对象
compareTo()比较两个枚举常量的大小

(3)注意
值得一提的是,java的枚举和C++中的枚举不一样,当我尝试使用values方法获取一下枚举的枚举值时,与预期结果不一样,C++中的枚举,实际上是整型常数的有限集合。C++编译会根据定义的顺序自动赋值为0,1,2,3…在java枚举中使用values()打印所有值,会出现一下结果:

enum Week{
	Sunday,
	Monday,
	Tuesday,
	Wednesday,
	Thursday,
	Friday,
	Saturday
}

打印结果
这是因为Week中的Sunday、Monday…Saturday均表示一个枚举对象,等同于:

enum Week{
	public static final Week Sunday = new Week();
	public static final Week Monday= new Week();
	public static final Week Tuesday= new Week();
	public static final Week Wednesday= new Week();
	public static final Week Thursday= new Week();
	public static final Week Friday= new Week();
	public static final Week Saturday= new Week();
}

values()方法的实现为:

public static Week values(){
	return (Week[]) $VALUES.clone();
}
//$VALUES为所有枚举常量
Week[] $VALUES = new Week[7];
$VALUES[0] = Sunday;
$VALUES[1] = Monday;
$VALUES[2] = Tuesday;
$VALUES[3] = Wednesday;
$VALUES[4] = Thursday;
$VALUES[5] = Friday;
$VALUES[6] = Saturday;
二、实现

具体流程如下:
请添加图片描述

WeekTest.java

package com.test.enumdemo;

import android.util.Log;

/**
 * @Author yang
 * @Date 2023/2/6
 */
public class WeekTest {

    enum Week{
        Sunday,
        Monday,
        Tuesday,
        Wednesday,
        Thursday,
        Friday,
        Saturday
    }

    public void setWeek(Week week){
        Log.d("dddddddddd", "setWeek: index="+week.ordinal());
    }
}

MainActivity.java

package com.test.enumdemo;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

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

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        testEnum();
    }
    private void testEnum(){
        try {
            //注意forName参数的美元符号
            //获取枚举的class
            Class clazz = Class
                    .forName("com.test.enumdemo.WeekTest$Week");
            Class<?> clazz1 = Class.forName("com.test.enumdemo.WeekTest");
            //创建对象
            Object obj = clazz1.newInstance();
            //获取对应的枚举对象
            Object[] enumConstants = clazz.getEnumConstants();
            Method method = clazz1.getMethod("setWeek",clazz);
            method.invoke(obj,enumConstants[1]);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
    }
}

打印结果:
在这里插入图片描述

三、优化

上面的实现方法是先获取了所有枚举对象,根据索引去传入对应的枚举对象,我们还可以直接创建枚举对象,实现如下:

private void testEnum(){
        try {
            //注意forName参数的美元符号
            //获取枚举的class
            Class clazz = Class
                    .forName("com.test.enumdemo.WeekTest$Week");
            Class<?> clazz1 = Class.forName("com.test.enumdemo.WeekTest");
            //创建对象
            Object obj = clazz1.newInstance();
            //获取对应的枚举对象
            Object param = Enum.valueOf(clazz,"Sunday");
            Method method = clazz1.getMethod("setWeek",clazz);
            method.invoke(obj,param);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
    }

打印结果如下:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值