14.反射

14.反射

通过Java的反射机制,可以更深入地控制程序的运行过程,如再程序运行时对用户输入的信息进行验证,还可以逆向控制程序的执行过程。此外Java在反射机制的基础上,还提供了Annotation功能

14.1Class类与Java反射

java.lang.reflect包中提供了对反射的支持,可以在程序中访问已经装载到JVM中的Java对象的描述,实现访问、检测和修改描述Java对象本身信息的功能。

所有java类均继承了Object类,在Object类中定义了一个getClass()方法,该方法返回某类的一个类型为Class的对象,举例如下:

Class textFieldC=textField.getClass();  //textField为JTextField类的对象

利用Class类的对象textFieldC,可以访问用来返回该对象的textField对象的 描述信息,常用的描述星系如下所示:

方法 返回值 功能描述
getPackage() Package对象 获得该类的存放路径
getName() String对象 获得该类的名称
getSuperclass() Class对象 获得该类的父类
getInterface() Class型数组 获得该类实现的所有接口
getConstructors() Constructor型数组 获得所有权限为public的构造方法
getConstructor(Class…parameterTypes) Constructor对象 获得权限为public的构造方法
getDeclaredConstructors() Constructor型数组 获得所有构造方法,按申明顺序返回
getDeclaredConstructor(Class…parameterTypes) Constructor对象 获得指定构造方法
getMethods() Method型数组 获得所有权限为public的方法
getMethod(String name,Class…parameterTypes) Method对象 获得指定方法
getDeclaredMethods() Method型数组 获得所有方法,按申明顺序返回
getDeclaredMethods(String name,Class…parameterTypes) Method对象 获得指定方法
getFields() Field型数组 获得所有权限为public的成员变量
·getField(String name) Field对象 获得权限为public的指定成员变量
getDeclaredFields() Field型数组 获得所有权限为public的成员变量
getDeclaredField(String name) Field对象 获得指定成员变量
getClasses() Class型数组 获得所有权限为public的内部类
getDeclaredClass() Class型对象 获得所有内部类
getDeclaringClass() Class对象 如果该类为内部类,则返回它的成员类,否则返回null

getFiled()和getMethods()方法依次获得权限为public的成员变量和方法时,包括从超类中继承到的成员变量和方法;而方法getDeclaredFields()和getDeclaredMethods()只是获得在本类中定义的所有成员变量和方法。

14.1.1访问构造方法

通过下列一组方法访问构造方法时,将返回Constructor类型的对象或者数组,每个Constructor对象代表一个构造方法,利用Constructor对象可以操纵相应构造方法。

getConstructors()

getConstructor(Class

objectClass.getDeclaredConstructor(String.class,int.class)
objectClass.getDeclaredConstructor(new Class[]{String.class,int.class})

Constructor类中提供的常用方法如下表:

方法 功能描述
isVarArgs() 查看该构造方法是否允许带有可变数量的参数,如果允许则返回true,否则返回false
getParameterTypes() 按照声明顺序以Class数组的形式获得该构造方法的各个参数类型
getExceptionTypes() 以Class数组的形式获得该构造方法可能抛出的异常类型
newInstance(Obejct..,.initargs) 通过该构造方法利用指定参数创建一个该类的对象,未设置参数则表示采用默认无参数构造方法
setAccessible(bollean flag) 当构造方法权限为private时,不允许直接使用newInstance(Obejct…initargs)方法创建对象,需要先执行该方法将参数入口设置为true
getModifiers() 获得可以解析该构造方法所采用修饰符的参数

通过java.lang.reflect.Modifier类可以解析出getMOdifiers()方法的返回值所表示的修饰符信息,在该类中提供了一系列用来解析的静态方法,既可以查看该构造方法是否被指定的修饰符修饰,还可以以字符串的形式获得所有修饰符,该类常用静态方法如下:

静态方法 功能描述
isPublic(int mod) 查看是否被public修饰符修饰,如果是则返回true,否则返回false
isProtected(int mod) 查看是否被protected修饰符修饰,如果是则返回true,否则返回false
isPrivate(int mod) 查看是否被private修饰符修饰,如果是则返回true,否则返回false
isStatic(int mod) 查看是否被static修饰符修饰,如果是则返回true,否则返回false
isFinal(int mod) 查看是否被final修饰符修饰,如果是则返回true,否者返回false
toString(int mod) 以字符串的形式返回所有修饰符

例如,判断对象constructor所代表的构造方法是否被private修饰,以及以字符串形式获得该构造方法的所有修饰符的典型代码如下:

int modifiers=constructor.getModifiers();
boolean isEmbellishByPrivate=Modifier.isPrivate(modifiers);
String embellishment=Modifier.toString(modifiers);

以下是一个访问构造方法的实例:

以下是一个Example_01类,该类中声明了3个构造方法:

import java.lang.reflect.Constructor;

public class Main_01 {
   
    public static void main(String[] args) {
        Example_01 example=new Example_01("10","20","30");
        Class<? extends Example_01>exampleC=example.getClass();
        //返回一个Example_01类的Class类对象
        //泛型中的<?>表示不确定类型
        Constructor[]declaredConstructors=exampleC.getDeclaredConstructors();
        //获得所有构造方法
        for(int i=0;i<declaredConstructors.length;i++){
            Constructor<?>constructor=declaredConstructors[i];
            System.out.println("查看是否允许带有可变数量的参数:"+constructor.isVarArgs());
            System.out.println("该构造方法的入口参数类型依次为:");
            Class[] parameterTypes=constructor.getParameterTypes();
            //获得所有参数类型
            for(int j=0;j<parameterTypes.length;j++){
                System.out.println(" "+parameterTypes[j]);
            }
            System.out.println("该构造方法可能抛出的异常类型为: ");
            //获得所有可能抛出的异常信息类型
            Class[]exceptionTypes=constructor.getExceptionTypes();
            for(int j=0;j<exceptionTypes.length;j++){
                System.out.println(" "+exceptionTypes[j]);
            }

            Example_01 example2=null;
            //在主方法最早的循环中,不同的i值对应不同的构造方法
            while(example2==null){
                try{
  //如果该成员变量的访问权限为private,则抛出异常,即不允许访问
                    if(i==2)//通过执行默认没有参数的构造方法创建对象
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
假设你有一个数据源 `List<T>`,需要对其进行分页操作。可以按照以下步骤编写分页方法: 1. 定义一个方法,接受三个参数:数据源 `List<T>`,页码 `int` 和每页的数据条数 `int`,返回值为当前页的数据列表 `List<T>`。 ```csharp public static List<T> GetPageData<T>(List<T> data, int pageIndex, int pageSize) { // TODO: 实现分页逻辑 } ``` 2. 计算数据总页数。 ```csharp int pageCount = (int)Math.Ceiling(data.Count / (double)pageSize); ``` 3. 根据页码和每页数据条数,计算出当前页的数据在数据源中的起始位置和结束位置。 ```csharp int startIndex = (pageIndex - 1) * pageSize; int endIndex = Math.Min(startIndex + pageSize, data.Count); ``` 4. 根据起始位置和结束位置,获取当前页的数据列表。 ```csharp List<T> pageData = data.GetRange(startIndex, endIndex - startIndex); ``` 完整的代码实现: ```csharp public static List<T> GetPageData<T>(List<T> data, int pageIndex, int pageSize) { int pageCount = (int)Math.Ceiling(data.Count / (double)pageSize); if (pageIndex < 1 || pageIndex > pageCount) { throw new ArgumentOutOfRangeException(nameof(pageIndex)); } int startIndex = (pageIndex - 1) * pageSize; int endIndex = Math.Min(startIndex + pageSize, data.Count); if (startIndex >= endIndex) { return new List<T>(); } return data.GetRange(startIndex, endIndex - startIndex); } ``` 在调用分页方法时,可以传入数据源、页码和每页数据条数,获取当前页的数据列表。 例如: ```csharp List<int> data = Enumerable.Range(1, 100).ToList(); List<int> pageData = GetPageData(data, 2, 10); // 输出:11, 12, 13, 14, 15, 16, 17, 18, 19, 20 Console.WriteLine(string.Join(", ", pageData)); ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值