util(泛型工具类GenericsUtils)

本文介绍了一个Java泛型工具类,提供了多种方法用于获取类、方法和字段的泛型参数实际类型。这些方法能够帮助开发者更好地管理和使用泛型,确保代码的类型安全。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package com.guwenren.util;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

import com.guwenren.bean.privilege.SystemPrivilege;
import com.guwenren.bean.privilege.SystemPrivilegePK;
import com.guwenren.web.action.privilege.Permission;
import com.sun.swing.internal.plaf.metal.resources.metal;
/**
 * 泛型工具类
 * @author guwenren
 *
 */
public class GenericsUtils {
    /**  
     * 通过反射,获得指定类的父类的泛型参数的实际类型. 如BuyerServiceBean extends DaoSupport<Buyer>  
     *  
     * @param clazz clazz 需要反射的类,该类必须继承范型父类
     * @param index 泛型参数所在索引,从0开始.  
     * @return 范型参数的实际类型, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回<code>Object.class</code>
     */  
    @SuppressWarnings({ "rawtypes" })
    public static Class getSuperClassGenricType(Class clazz, int index) {    
        Type genType = clazz.getGenericSuperclass();//得到泛型父类  
        //如果没有实现ParameterizedType接口,即不支持泛型,直接返回Object.class   
        if (!(genType instanceof ParameterizedType)) {
            return Object.class;   
        }  
        //返回表示此类型实际类型参数的Type对象的数组,数组里放的都是对应类型的Class, 如BuyerServiceBean extends DaoSupport<Buyer,Contact>就返回Buyer和Contact类型   
        Type[] params = ((ParameterizedType) genType).getActualTypeArguments();                   
        if (index >= params.length || index < 0) { 
             throw new RuntimeException("你输入的索引"+ (index<0 ? "不能小于0" : "超出了参数的总数"));
        }      
        if (!(params[index] instanceof Class)) {
            return Object.class;   
        }   
        return (Class) params[index];
    }
    /**  
     * 通过反射,获得指定类的父类的第一个泛型参数的实际类型. 如BuyerServiceBean extends DaoSupport<Buyer>  
     *  
     * @param clazz clazz 需要反射的类,该类必须继承泛型父类
     * @return 泛型参数的实际类型, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回<code>Object.class</code>
     */  
    @SuppressWarnings({ "rawtypes" })
    public static Class getSuperClassGenricType(Class clazz) {
        return getSuperClassGenricType(clazz,0);
    }
    /**  
     * 通过反射,获得方法返回值泛型参数的实际类型. 如: public Map<String, Buyer> getNames(){}
     *  
     * @param Method method 方法
     * @param int index 泛型参数所在索引,从0开始.
     * @return 泛型参数的实际类型, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回<code>Object.class</code>
     */ 
    @SuppressWarnings("rawtypes")
    public static Class getMethodGenericReturnType(Method method, int index) {
        Type returnType = method.getGenericReturnType();
        if(returnType instanceof ParameterizedType){
            ParameterizedType type = (ParameterizedType) returnType;
            Type[] typeArguments = type.getActualTypeArguments();
            if (index >= typeArguments.length || index < 0) { 
                 throw new RuntimeException("你输入的索引"+ (index<0 ? "不能小于0" : "超出了参数的总数"));
            } 
            return (Class)typeArguments[index];
        }
        return Object.class;
    }
    /**  
     * 通过反射,获得方法返回值第一个泛型参数的实际类型. 如: public Map<String, Buyer> getNames(){}
     *  
     * @param Method method 方法
     * @return 泛型参数的实际类型, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回<code>Object.class</code>
     */ 
    @SuppressWarnings("rawtypes")
    public static Class getMethodGenericReturnType(Method method) {
        return getMethodGenericReturnType(method, 0);
    }
    
    /**  
     * 通过反射,获得方法输入参数第index个输入参数的所有泛型参数的实际类型. 如: public void add(Map<String, Buyer> maps, List<String> names){}
     *  
     * @param Method method 方法
     * @param int index 第几个输入参数
     * @return 输入参数的泛型参数的实际类型集合, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回空集合
     */ 
    @SuppressWarnings("rawtypes")
    public static List<Class> getMethodGenericParameterTypes(Method method, int index) {
        List<Class> results = new ArrayList<Class>();
        Type[] genericParameterTypes = method.getGenericParameterTypes();
        if (index >= genericParameterTypes.length ||index < 0) {
             throw new RuntimeException("你输入的索引"+ (index<0 ? "不能小于0" : "超出了参数的总数"));
        } 
        Type genericParameterType = genericParameterTypes[index];
        if(genericParameterType instanceof ParameterizedType){
             ParameterizedType aType = (ParameterizedType) genericParameterType;
             Type[] parameterArgTypes = aType.getActualTypeArguments();
             for(Type parameterArgType : parameterArgTypes){
                 Class parameterArgClass = (Class) parameterArgType;
                 results.add(parameterArgClass);
             }
             return results;
        }
        return results;
    }
    /**  
     * 通过反射,获得方法输入参数第一个输入参数的所有泛型参数的实际类型. 如: public void add(Map<String, Buyer> maps, List<String> names){}
     *  
     * @param Method method 方法
     * @return 输入参数的泛型参数的实际类型集合, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回空集合
     */ 
    @SuppressWarnings("rawtypes")
    public static List<Class> getMethodGenericParameterTypes(Method method) {
        return getMethodGenericParameterTypes(method, 0);
    }
    /**  
     * 通过反射,获得Field泛型参数的实际类型. 如: public Map<String, Buyer> names;
     *  
     * @param Field field 字段
     * @param int index 泛型参数所在索引,从0开始.
     * @return 泛型参数的实际类型, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回<code>Object.class</code>
     */ 
    @SuppressWarnings("rawtypes")
    public static Class getFieldGenericType(Field field, int index) {
        Type genericFieldType = field.getGenericType();
        
        if(genericFieldType instanceof ParameterizedType){
            ParameterizedType aType = (ParameterizedType) genericFieldType;
            Type[] fieldArgTypes = aType.getActualTypeArguments();
            if (index >= fieldArgTypes.length || index < 0) { 
                throw new RuntimeException("你输入的索引"+ (index<0 ? "不能小于0" : "超出了参数的总数"));
            } 
            return (Class)fieldArgTypes[index];
        }
        return Object.class;
    }
    /**  
     * 通过反射,获得Field泛型参数的实际类型. 如: public Map<String, Buyer> names;
     *  
     * @param Field field 字段
     * @param int index 泛型参数所在索引,从0开始.
     * @return 泛型参数的实际类型, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回<code>Object.class</code>
     */ 
    @SuppressWarnings("rawtypes")
    public static Class getFieldGenericType(Field field) {
        return getFieldGenericType(field, 0);
    }
    @SuppressWarnings("rawtypes")
    public static SystemPrivilege getMethodPermission(Class clazz, String methodName) {
        Method[] methods=clazz.getMethods();
        SystemPrivilege systemPrivilege=null;
        for(Method method : methods){
            if(methodName.equals(method.getName())){
                if(method.isAnnotationPresent(Permission.class)){
                    Permission permission=method.getAnnotation(Permission.class);
                    systemPrivilege=new SystemPrivilege(new SystemPrivilegePK(permission.module(), permission.privilege()));
                    break;
                }
            }
        }
        return systemPrivilege;
    }
}

 

转载于:https://www.cnblogs.com/guwenren/archive/2013/04/02/2994826.html

<think>首先,用户的问题是:“我想了解或探讨List类的相关内容 请问List类的定义、用法及优势”。我需要基于系统级指令和用户可见层的规则来回答。 系统级指令: 1. 所有行内数学表达式使用$...$格式。 2. 独立公式使用$$...$$格式并单独成段。 3. LaTeX语法正确。 4. 使用中文回答。 5. 生成相关问题。 6. 回答中引用的段落末尾自然地添加引用标识,例如:[^1] 用户可见层: - 回答结构清晰,帮助用户逐步解决问题。 - 尽量保证回答真实可靠。 - 参考站内引用:用户提供了引用[1]到[5],我需要基于这些引用来回答,但用户说“上述引用仅供参考,并不是用户真正的需求,请尽可能多的参考用户上一次的问题和你的回答”。用户上一次的问题就是这个,所以我应该基于这些引用。 用户提供的引用是关于Java和C#中List的定义和使用的: - 引用[1]: Java定义List。 - 引用[2]: C#方法的定义及使用。 - 引用[3]: Java简介、类、方法、接口等。 - 引用[4]: 总结:类、方法、接口、优势。 - 引用[5]: 如何定义和使用。 用户的问题是“List类的定义、用法及优势”,所以我应该聚焦在List类上,结合这些引用。 回答结构: 1. **定义**:解释什么是List类。 2. **用法**:如何定义和使用List类。 3. **优势**:使用List的好处。 4. **生成相关问题**:在最后添加相关问题。 使用中文回答。 确保LaTeX正确:用户的问题中没有数学表达式,但如果有,我需要用$...$或$$...$$。在中,可能涉及类参数如<T>,这不是数学表达式,所以不需要LaTeX。但如果有公式,比如在优势中,可能需要,但这里可能没有。所以,我可能不需要使用数学格式。 引用标识:在回答中,如果引用站内内容,在末尾添加[^n]。用户提供了引用[1]到[5],所以我应该引用它们。 步骤: - 先定义List类。 - 然后解释用法,包括定义和使用。 - 最后讨论优势。 - 最后添加相关问题。 参考引用: - 引用[1]: Java中定义List,类参数化。 - 引用[2]: C#中List,使用GenericList<T>示例。 - 引用[3]: Java类、方法等。 - 引用[4]: 优势,如类安全、避免转换。 - 引用[5]: 接口的实现。 由于用户问的是List类,我应该通用化,但引用是Java和C#特定的。我可以结合两者,但以Java为主,因为引用中Java更多。 用户的问题没有指定语言,但引用包括Java和C#。我应该以通用方式回答,但基于引用。 结构化回答: 1. **引言**:简要介绍List类。 2. **定义**:什么是List类。 3. **用法**: - 如何定义List类。 - 如何使用它(创建实例、添加元素等)。 4. **优势**:列出主要优势。 5. **相关问题**:生成几个相关问题。 在回答中,自然地引用: - 例如,当提到定义时,引用[1]或[3]。 - 当提到优势时,引用[4]。 最终添加相关问题。</think>### List类的定义、用法及优势 List类是编程中一种强大的数据结构,它允许在定义列表时指定元素类,从而在编译期提供类安全。(Generics)是一种类参数化的技术,通过引入类参数(如`T`),使代码更灵活、可重用。下面我将基于Java和C#等语言的实际实现,逐步解释List类的核心内容,确保回答清晰可靠(参考了站内相关引用)。 #### 1. **List类的定义** List类是通过在类声明中添加类参数来定义的,例如`List<T>`,其中`T`是一个占位符,代表任意类(如`String`、`Integer`或自定义类)。这样,List在编译时就能约束元素类,避免运行时错误。List的核心是类安全:它确保列表只能存储指定类的元素,并在操作时自动处理类转换。 在Java中,List通常基于`java.util.List`接口实现,如`ArrayList<T>`。定义时,在类名后添加尖括号`<>`来指定类参数: ```java // 定义List类 public class GenericList<T> { private List<T> items = new ArrayList<>(); public void add(T item) { items.add(item); } public T get(int index) { return items.get(index); } } ``` 这里,`T`是类参数,使用时可以替换为具体类(如`String`或`Integer`)[^1][^3]。 在C#中,List类似,使用`List<T>`类: ```csharp public class GenericList<T> { private List<T> items = new List<T>(); public void Add(T item) { items.Add(item); } } ``` List的本质是参数化类,它允许开发者在设计阶段抽象出数据类,使用时再具体化,从而提升代码的通用性[^2][^4]。 #### 2. **List类的用法** List的使用分为定义和实例化两个阶段,确保类安全且避免显式类转换。以下是关键步骤和示例: - **定义List**:在类或接口声明中,使用`<T>`指定类参数。类参数`T`可以用于方法参数、返回值或内部数据结构。 - Java示例:定义一个List类。 ```java public class MyList<T> { private List<T> list = new ArrayList<>(); public void addItem(T item) { list.add(item); } public T getItem(int index) { return list.get(index); } } ``` 这里,`MyList<T>`是一个类,`T`可以是任何引用类[^1][^3]。 - C#示例:定义方法。 ```csharp public class ListUtils { public static void AddItem<T>(List<T> list, T item) { list.Add(item); } } ``` 方法在方法名后加`<T>`,允许在单个方法中处理多种类[^2]。 - **使用List**:实例化时指定具体类,编译器会强制类检查。 - Java示例:创建并操作List。 ```java public static void main(String[] args) { // 创建String类的List MyList<String> stringList = new MyList<>(); stringList.addItem("Hello"); System.out.println(stringList.getItem(0)); // 输出: Hello // 创建Integer类的List MyList<Integer> intList = new MyList<>(); intList.addItem(123); // intList.addItem("abc"); // 编译错误:类不匹配 } ``` 使用后,添加错误类元素会导致编译期错误,而不是运行时异常[^3][^4]。 - C#示例:使用内置`List<T>`。 ```csharp List<string> names = new List<string>(); names.Add("Alice"); // names.Add(123); // 编译错误:类不匹配 ``` List简化了代码,无需手动转换类[^2]。 关键用法点: - **类推断**:在Java 7+和C#中,可以使用`new ArrayList<>()`(菱形运算符),编译器自动推断类[^4]。 - **接口**:List类可以实现接口,如`List<T>`在Java中继承自`Collection<T>`[^5]。 - **通配符**:处理未知类时,使用`<?>`(Java)或`<? extends T>`(C#),例如`List<?>`可以接受任何类,但添加元素受限[^3][^4]。 #### 3. **List类的优势** List的主要优势在于提升代码的可靠性、效率和可维护性: - **类安全**:编译期类检查防止了`ClassCastException`等运行时错误。例如,在非List中,添加`Object`类元素可能导致转换错误;而List强制元素类一致,减少bug[^1][^4]。 - **避免装箱/拆箱**:对于值类(如`int`在Java或C#),List直接操作原始类,避免性能开销(如Java的`ArrayList<Integer>`无需频繁装箱)[^2][^4]。 - **代码重用**:通过类参数化,一个List类可以处理多种数据类,减少重复代码。例如,同一个`GenericList<T>`类可用于字符串、整数或自定义对象[^1][^3]。 - **可读性和维护性**:代码更清晰,开发者一眼看出列表的元素类,便于调试和扩展[^4]。 - **性能优化**:在编译时解析类,运行时无额外开销(相比非的强制转换),提升执行效率[^2][^4]。 总之,List类是现代编程的核心工具,尤其在集合框架中(如Java的`ArrayList<T>`或C#的`List<T>`),它通过类参数化实现了更强的抽象和安全性[^1][^2][^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值