精华内容
下载资源
问答
  • Java中通过反射获取参数类型方法 问题的提出 在后端与前端进行数据传送时,需要先把数据进行类型转换,从前端获得的字符串类型(由json类型数据转化而成),转换成一个Java类。通过了解,发现可以采用导入Gson包...

    date: 2021/8/16

    author: jzh

    blog: https://akynazh.top


    Java中通过反射获取带参数类型的方法

    问题的提出

    在后端与前端进行数据传送时,需要先把数据进行类型转换,从前端获得的字符串类型(由json类型数据转化而成),转换成一个Java类。通过了解,发现可以采用导入Gson包的方式调用方法实现这个功能:

    Person p = new Person(1, "jzh");
    Gson gson = new Gson();
    String p_json = gson.toJson(p);
    Person p1 = gson.fromJson(p_json, Person.class);
    

    从中可见gson.fromJson的第二个参数就是一个类对象,针对于无参的类可以直接通过.class获取类对象,然而有参怎么办呢?如下:

    ArrayList<Person> people = new ArrayList<>();
    people.add(new Person(1, "jzh"));
    people.add(new Person(2, "zh"));
    people.add(new Person(3, "z"));
    String ps_json = gson.toJson(people);
    ArrayList<Person> people1 = gson.fromJson(ps_json,new TypeToken<ArrayList<Person>>() {
            }.getType());
    

    这里通过创建匿名内部类的方式实现了转换,也可以通过创建类继承于TypeToken实现。

    class MyType extends TypeToken<ArrayList<Person>> {}
    
    ArrayList<Person> people1 = gson.fromJson(ps_json, new MyType().getType());
    

    那么问题来了,这里底层是怎么实现转换的呢?为什么要使用TypeToken?

    问题的思考与解决

    首先我们通过阅读源码寻找答案。

    gson源码中的TypeToken类:

    public class TypeToken<T> {
        final Class<? super T> rawType;
        final Type type;
        final int hashCode;
    }
    

    constructor:

    protected TypeToken() {
        this.type = getSuperclassTypeParameter(getClass());
        this.rawType = (Class<? super T>) $Gson$Types.getRawType(type);
        this.hashCode = type.hashCode();
    }
    

    这里我们主要研究type成员。

    通过方法getSuperclassTypeParameter:

    static Type getSuperclassTypeParameter(Class<?> subclass) {
        Type superclass = subclass.getGenericSuperclass();
        if (superclass instanceof Class) {
            throw new RuntimeException("Missing type parameter.");
        }
        ParameterizedType parameterized = (ParameterizedType) superclass;
        return $Gson$Types.canonicalize(parameterized.getActualTypeArguments()[0]);
    }
    

    在这里我们就可以找到答案了:

    分析可知,步骤如下:

    • 从一个Class对象中,获取该对象父类接收到的参数化类型(泛型)
    • 判断type类型
    • 强制转换为ParameterizedType类型
    • 获取parameterized的第一个参数

    一. 从一个Class对象中,获取该对象父类接收到的参数化类型(泛型)

    Type superclass = subclass.getGenericSuperclass();
    

    其中subclass为:

    class 包名.Type.TypeTest.TypeToken<java.util.ArrayList<包名.Type.Person>>

    通过前面知道,我们通过继承(或者匿名内部类)的方式创建了一个类,那么我们则可以通过getGenericSuperclass()方法获取这个类的父类,而且是包含了我们需要的类型参数的父类!

    二. 判断type类型

    if (superclass instanceof Class) {
    	throw new RuntimeException("Missing type parameter."); // 不是带参数类型
    }
    

    Type是一个接口,Class,ParameterizedType等类型都实现了Type,我们需要确保传入的类型参数是一个带参数的类ParameterizedType而不是Class。

    三. 强制转换为ParameterizedType类型,即带参数类型,可以调用对应方法获取参数

    ParameterizedType parameterized = (ParameterizedType) superclass;
    

    parameterized : 包名.Type.TypeToken<java.util.ArrayList<包名.Type.Person>>

    四. 获取parameterized的第一个参数,即java.util.ArrayList<包名.Type.Person>

    parameterized.getActualTypeArguments()[0];
    

    源码中的canonicalize方法是实例化一个ParameterizedTypeImpl对象的方法,可以不予理会。

    总结

    过程粗略一看貌似有些奇怪,但是分析其思路,用通俗的话描述就是,将一个加密的东西放进一个解密的机器里面,在把东西拿出来,你就知道东西具体是什么了!

    那么为什么需要一个TypeToken进行包裹呢,个人认为,因为有一个方法getGenericSuperclass可以获得包含了参数类型的父类,用一个类继承于TypeToken, 指定T为自定义的参数类型如ArrayList, 通过调用getGenericSuperclass获取父类,把父类强制转换为ParameterizedType类型,即带参数类型,即可调用对应方法获取参数。


    date: 2021/8/16

    author: jzh

    blog: https://akynazh.top

    展开全文
  • /*** 根据方法名称取得反射方法参数类型(没有考虑同名重载方法使用时注意)* @param obj 类实例* @param methodName 方法名* @return* @throws ClassNotFoundException*/public static Class[] getMethodParamTypes...

    /**

    * 根据方法名称取得反射方法的参数类型(没有考虑同名重载方法使用时注意)

    * @param obj         类实例

    * @param methodName  方法名

    * @return

    * @throws ClassNotFoundException

    */

    public static Class[]  getMethodParamTypes(Object classInstance,

    String methodName) throws ClassNotFoundException{

    Class[] paramTypes = null;

    Method[]  methods = classInstance.getClass().getMethods();//全部方法

    for (int  i = 0;  i< methods.length; i++) {

    if(methodName.equals(methods[i].getName())){//和传入方法名匹配

    Class[] params = methods[i].getParameterTypes();

    paramTypes = new Class[ params.length] ;

    for (int j = 0; j < params.length; j++) {

    paramTypes[j] = Class.forName(params[j].getName());

    }

    break;

    }

    }

    return paramTypes;

    }

    //取得方法测试(Test类大家还是任意写吧,这里不列举了)

    Method m =  Test.class.newInstance().getClass().getDeclaredMethod("方法名称",getMethodParamTypes(Test.class.newInstance(),"方法名称"));

    总结

    如果觉得编程之家网站内容还不错,欢迎将编程之家网站推荐给程序员好友。

    本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。

    如您喜欢交流学习经验,点击链接加入交流1群:1065694478(已满)交流2群:163560250

    展开全文
  • 例:我知道方法参数是Boolean.TRUE,Arrays.asList(“foo”,“bar”,“baz”)和BigInteger.valueOf(77777l)我的类包含一个带签名的方法public foo(boolean, Collection, Number)我无法直接将参数映射到参数类型,因为...

    当我必须查找方法时,我通常做的是从我正在进行的查询生成缓存键,并将此缓存键保存在地图中.

    例:

    我知道方法参数是Boolean.TRUE,Arrays.asList(“foo”,“bar”,“baz”)和BigInteger.valueOf(77777l)

    我的类包含一个带签名的方法

    public foo(boolean, Collection, Number)

    我无法直接将参数映射到参数类型,因为我只是不知道哪个超类或接口是参数类型,如下表所示:

    Expected Type | What I have

    -----------------------------------------------------

    boolean | java.lang.Boolean

    java.util.Collection | java.util.Arrays$ArrayList

    java.lang.Number | java.math.BigInteger

    这些对中的每一对都是兼容的,但是没有定义比较方法就无法找到兼容的方法,如下所示:

    // determine whether a method's parameter types are compatible

    // with my arg array

    public static boolean isCompatible(final Method method,

    final Object[] params) throws Exception{

    final Class>[] parameterTypes = method.getParameterTypes();

    if(params.length != parameterTypes.length){

    return false;

    }

    for(int i = 0; i < params.length; i++){

    final Object object = params[i];

    final Class> paramType = parameterTypes[i];

    if(!isCompatible(object, paramType)){

    return false;

    }

    }

    return true;

    }

    // determine whether a single object is compatible with

    // a single parameter type

    // careful: the object may be null

    private static boolean isCompatible(final Object object,

    final Class> paramType) throws Exception{

    if(object == null){

    // primitive parameters are the only parameters

    // that can't handle a null object

    return !paramType.isPrimitive();

    }

    // handles same type, super types and implemented interfaces

    if(paramType.isInstance(object)){

    return true;

    }

    // special case: the arg may be the Object wrapper for the

    // primitive parameter type

    if(paramType.isPrimitive()){

    return isWrapperTypeOf(object.getClass(), paramType);

    }

    return false;

    }

    /*

    awful hack, can be made much more elegant using Guava:

    return Primitives.unwrap(candidate).equals(primitiveType);

    */

    private static boolean isWrapperTypeOf(final Class> candidate,

    final Class> primitiveType) throws Exception{

    try{

    return !candidate.isPrimitive()

    && candidate

    .getDeclaredField("TYPE")

    .get(null)

    .equals(primitiveType);

    } catch(final NoSuchFieldException e){

    return false;

    } catch(final Exception e){

    throw e;

    }

    }

    所以我要做的是有一个方法缓存:

    private static final Map> methodCache;

    并添加这样的查找方法:

    public static Set getMatchingMethods(final Class> clazz,

    final Object[] args) throws Exception{

    final String cacheKey = toCacheKey(clazz, args);

    Set methods = methodCache.get(cacheKey);

    if(methods == null){

    final Set tmpMethods = new HashSet();

    for(final Method candidate : clazz.getDeclaredMethods()){

    if(isCompatible(candidate, args)){

    tmpMethods.add(candidate);

    }

    }

    methods = Collections.unmodifiableSet(tmpMethods);

    methodCache.put(cacheKey, methods);

    }

    return methods;

    }

    private static String toCacheKey(final Class> clazz, final Object[] args){

    final StringBuilder sb = new StringBuilder(clazz.getName());

    for(final Object obj : args){

    sb.append('-').append(

    obj == null ? "null" : obj.getClass().getName());

    }

    return sb.toString();

    }

    这样,后续查找将比第一次查找花费的时间少得多(对于相同类型的参数).

    当然,因为Class.getDeclaredMethods()在内部使用缓存,所以问题在于我的缓存是否会提高性能.这基本上是一个更快的问题:

    >生成缓存密钥并查询HashMap或

    >迭代所有方法并查询参数兼容性

    我猜:对于大班(很多方法),第一种方法会胜出,否则第二种方法会胜出

    展开全文
  • 一般来说,通过反射是很难获得参数名的,只能取到参数类型,因为在编译时,参数名有可能是会改变的,需要在编译时加入参数才不会改变。使用注解是可以实现取类型名(或者叫注解名)的,但是要写注解,并不方便。观察...

    一般来说,通过反射是很难获得参数名的,只能取到参数类型,因为在编译时,参数名有可能是会改变的,需要在编译时加入参数才不会改变。

    使用注解是可以实现取类型名(或者叫注解名)的,但是要写注解,并不方便。

    观察Spring mvc框架中的数据绑定,发现是可以直接把http请求中对应参数绑定到对应的参数名上的,他是怎么实现的呢?

    在getMethodArgumentValues方法中,MethodParameter[] parameters = getMethodParameters();这一句取到方法的所有参数,MethodParameter类型中有方法名的属性,这个是什么类呢?

    是spring核心中的一个类,org.springframework.core.MethodParameter,并不是通过反射实现的。

    方法getMethodParameters()是在HandlerMethod的类中

    publicMethodParameter[] getMethodParameters() {

    return this.parameters;

    }

    this.parameters则是在构造方法中初始化的:

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    publicHandlerMethod(Object bean, Method method) {

    Assert.notNull(bean, "Bean is required");

    Assert.notNull(method, "Method is required");

    this.bean =bean;

    this.beanFactory = null;

    this.method =method;

    this.bridgedMethod =BridgeMethodResolver.findBridgedMethod(method);

    this.parameters =initMethodParameters();

    }

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    initMethodParameters()生成了参数列表。

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    privateMethodParameter[] initMethodParameters() {

    int count = this.bridgedMethod.getParameterTypes().length;

    MethodParameter[] result = newMethodParameter[count];

    for (int i = 0; i < count; i++) {

    result[i] = newHandlerMethodParameter(i);

    }

    returnresult;

    }

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    HandlerMethodParameter(i)是HandlerMethod的内部类,继承自MethodParameter

    构造方法调用:

    public HandlerMethodParameter(intindex) {

    super(HandlerMethod.this.bridgedMethod, index);

    }

    再调用MethodParameter类的构造方法:

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    public MethodParameter(Method method, int parameterIndex, intnestingLevel) {

    Assert.notNull(method, "Method must not be null");

    this.method =method;

    this.parameterIndex =parameterIndex;

    this.nestingLevel =nestingLevel;

    this.constructor = null;

    }

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    MethodParameter类中有private String parameterName;储存的就是参数名,但是构造方法中并没有设置他的值,真正设置值是在:

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    publicString getParameterName() {

    if (this.parameterNameDiscoverer != null) {

    String[] parameterNames = (this.method != null ?

    this.parameterNameDiscoverer.getParameterNames(this.method) :

    this.parameterNameDiscoverer.getParameterNames(this.constructor));

    if (parameterNames != null) {

    this.parameterName = parameterNames[this.parameterIndex];

    }

    this.parameterNameDiscoverer = null;

    }

    return this.parameterName;

    }

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    而parameterNameDiscoverer就是用来查找名称的,他在哪里设置的值呢?

    public voidinitParameterNameDiscovery(ParameterNameDiscoverer parameterNameDiscoverer) {

    this.parameterNameDiscoverer =parameterNameDiscoverer;

    }

    这是个public方法,哪里调用了这个方法呢?有六七个地方吧,但是主要明显的是这里:

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    privateObject[] getMethodArgumentValues(NativeWebRequest request, ModelAndViewContainer mavContainer,

    Object... providedArgs) throwsException {

    MethodParameter[] parameters =getMethodParameters();

    Object[] args = newObject[parameters.length];

    for (int i = 0; i < parameters.length; i++) {

    MethodParameter parameter =parameters[i];

    parameter.initParameterNameDiscovery(this.parameterNameDiscoverer);

    GenericTypeResolver.resolveParameterType(parameter, getBean().getClass());

    args[i] =resolveProvidedArgument(parameter, providedArgs);

    if (args[i] != null) {

    continue;

    }

    if (this.argumentResolvers.supportsParameter(parameter)) {

    try{

    args[i] = this.argumentResolvers.resolveArgument(

    parameter, mavContainer, request, this.dataBinderFactory);

    continue;

    }

    catch(Exception ex) {

    if(logger.isTraceEnabled()) {

    logger.trace(getArgumentResolutionErrorMessage("Error resolving argument", i), ex);

    }

    throwex;

    }

    }

    if (args[i] == null) {

    String msg = getArgumentResolutionErrorMessage("No suitable resolver for argument", i);

    throw newIllegalStateException(msg);

    }

    }

    returnargs;

    }

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    又回到了初始方法,这里面对ParameterNameDiscovery初始化,用来查找参数名:

    methodParam.initParameterNameDiscovery(this.parameterNameDiscoverer);

    this.parameterNameDiscoverer又是什么呢?

    private ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();

    通过DefaultParameterNameDiscoverer类的实例来查找参数名。

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    /*** Default implementation of the {@linkParameterNameDiscoverer} strategy interface,

    * using the Java 8 standard reflection mechanism (if available), and falling back

    * to the ASM-based {@linkLocalVariableTableParameterNameDiscoverer} for checking

    * debug information in the class file.

    *

    *

    Further discoverers may be added through {@link#addDiscoverer(ParameterNameDiscoverer)}.

    *

    * @authorJuergen Hoeller

    * @since4.0

    * @seeStandardReflectionParameterNameDiscoverer

    * @seeLocalVariableTableParameterNameDiscoverer

    */

    public class DefaultParameterNameDiscoverer extendsPrioritizedParameterNameDiscoverer {

    private static final boolean standardReflectionAvailable =(JdkVersion.getMajorJavaVersion() >=JdkVersion.JAVA_18);

    publicDefaultParameterNameDiscoverer() {

    if(standardReflectionAvailable) {

    addDiscoverer(newStandardReflectionParameterNameDiscoverer());

    }

    addDiscoverer(newLocalVariableTableParameterNameDiscoverer());

    }

    }

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    这个是类声明,因为java1.8是支持从反射获取参数名的(具体参考网络)

    低于1.8时使用new LocalVariableTableParameterNameDiscoverer()来解析参数名。

    其中有方法:

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    publicString[] getParameterNames(Method method) {

    Method originalMethod =BridgeMethodResolver.findBridgedMethod(method);

    Class> declaringClass =originalMethod.getDeclaringClass();

    Map map = this.parameterNamesCache.get(declaringClass);

    if (map == null) {

    map =inspectClass(declaringClass);

    this.parameterNamesCache.put(declaringClass, map);

    }

    if (map !=NO_DEBUG_INFO_MAP) {

    returnmap.get(originalMethod);

    }

    return null;

    }

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    通过map = inspectClass(declaringClass);获取名称map。

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    private Map inspectClass(Class>clazz) {

    InputStream is =clazz.getResourceAsStream(ClassUtils.getClassFileName(clazz));

    if (is == null) {

    //We couldn't load the class file, which is not fatal as it

    //simply means this method of discovering parameter names won't work.

    if(logger.isDebugEnabled()) {

    logger.debug("Cannot find '.class' file for class [" +clazz

    + "] - unable to determine constructors/methods parameter names");

    }

    returnNO_DEBUG_INFO_MAP;

    }

    try{

    ClassReader classReader = newClassReader(is);

    Map map = new ConcurrentHashMap(32);

    classReader.accept(new ParameterNameDiscoveringVisitor(clazz, map), 0);

    returnmap;

    }

    catch(IOException ex) {

    if(logger.isDebugEnabled()) {

    logger.debug("Exception thrown while reading '.class' file for class [" + clazz +

    "] - unable to determine constructors/methods parameter names", ex);

    }

    }

    catch(IllegalArgumentException ex) {

    if(logger.isDebugEnabled()) {

    logger.debug("ASM ClassReader failed to parse class file [" + clazz +

    "], probably due to a new Java class file version that isn't supported yet " +

    "- unable to determine constructors/methods parameter names", ex);

    }

    }

    finally{

    try{

    is.close();

    }

    catch(IOException ex) {

    //ignore

    }

    }

    returnNO_DEBUG_INFO_MAP;

    }

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    这是方法。。。由此可见,spring是直接读取class文件来读取参数名的。。。。。。。。。。。。真累

    反射的method类型为public java.lang.String com.guangshan.data.DataPoolController.addData(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse,java.lang.String,org.springframework.ui.Model)

    所以需要通过类型查找参数名。

    调试过程:反向调用过程:

    1、

    a616041b5445d6e27dd74547c0e73c63.png

    classReader.accept(new ParameterNameDiscoveringVisitor(clazz, map), 0);

    classReader位于org.springframework.asm包中,是spring用于反编译的包,读取class信息,class信息中是包含参数名的(可以用文本编辑器打开一个class文件查看,虽然有乱码,但是方法的参数名还在)

    通过accept填充map对象,map的键为成员名(方法名或者参数名),值为参数列表(字符串数组)。

    2、

    a497b5e9cdc93e70773efbe487cd04e6.png

    生成map之后,添加至参数名缓存,parameterNamesCache是以所在类的class为键,第一步的map为值的map。

    3、

    baa30029c39b44b870239005903acf3a.png

    通过第一步的map获取方法中的参数名数组。

    4、

    5de8dd0f53d33ecf8a1ac2488ae5e8c4.png

    通过调用本类parameterNameDiscoverer,再获取参数名的列表。

    5、

    caafa5340919c3e5442ca3e31f8f803d.png

    6、

    cb7357a4bb6a037c3be32b8d118f2344.png

    7、

    65505d984ec7c59522a6f1631616de09.png

    最终回到数据绑定的方法

    2016年6月6日11:45:59补充:

    @Aspect的注解里面,参数有一个叫做JoinPoint的,这个JoinPoint里面也可以获取参数名:

    Signature signature = joinPoint.getSignature();

    MethodSignature methodSignature = (MethodSignature) signature;

    MethodSignature有方法:public String[] getParameterNames()

    实现在:MethodInvocationProceedingJoinPoint类的MethodSignatureImpl类中:

    this.parameterNames = parameterNameDiscoverer.getParameterNames(getMethod());

    parameterNameDiscoverer是:DefaultParameterNameDiscoverer:

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    public class DefaultParameterNameDiscoverer extendsPrioritizedParameterNameDiscoverer {

    private static final boolean standardReflectionAvailable =(JdkVersion.getMajorJavaVersion() >=JdkVersion.JAVA_18);

    publicDefaultParameterNameDiscoverer() {

    if(standardReflectionAvailable) {

    addDiscoverer(newStandardReflectionParameterNameDiscoverer());

    }

    addDiscoverer(newLocalVariableTableParameterNameDiscoverer());

    }

    }

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    判断版本,因为java8可以通过反射获取参数名,但是需要使用-parameters参数开启这个功能

    可以看到有两个StandardReflectionParameterNameDiscoverer、LocalVariableTableParameterNameDiscoverer

    一个是通过标准反射来获取,一个是通过解析字节码文件的本地变量表来获取的。

    Parameter对象是新的反射对象,param.isNamePresent()表示是否编译了参数名。

    展开全文
  • java反射获取方法名称,参数类型

    千次阅读 2021-02-12 13:22:00
    import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;//通过反射获取方法信息public class getMethodUtil {public static void main(String[] ar...
  • java原始的反射是不能获取方法菜蔬的名称的..这里借住了地方jar包使用maven管理jarorg.javassistjavassist3.18.1-GAjava示范代码Class clazz = IExample.class;try {ClassPool pool = ClassPool.getDefault();...
  • while (cellbody.hasNext()) {Cell cell = cellbody.next();// 这里得到此列的对应的...// 如果这一列的标题和类中的某一列的Annotation相同,那么则调用此类的的set方法,进行设值if (fieldmap.containsKey(titleSt...
  • 默认情况下,我们是无法获取方法参数的名称,通过反射机制也只能过去参数的顺序以及一些表意名:arg0、arg1等等;当我们面对,比如文档化服务接口的详细信息时,就会比较麻烦。因为源文件在编译时,不会将参数名称...
  • interface Foo { ... }class Bar implements Foo { ... }I've got a Bar object. How to get the value of T for it (Baz)?So far, I only managed to get the interface and T, but I can't see a way to get its v...
  • for(Method m : methods2) {//获取方法的所有参数 Parameter[] parameters =m.getParameters();for(Parameter p : parameters) {//判断是否存在注解 if(p.isAnnotationPresent(ParamAu.class)){ System.out.println...
  • 解决方法: 如果您只是键入提示类,则可以使用PHP 5和7中支持的->getClass(). class MyClass { } class Foo { public function test(stdClass $bar) { } public function another_test(array $arr) { } public ...
  • private Method forget;private Method connect_netID;private Method connect_wifiConfig;private Method save;public Compatimpl17() {try {Class ActionListener = Class.forName("android.net.wifi.WifiManager$...
  • PHP的反射动态获取方法、属性、参数操作。,具体如下:我们可以在PHP运行时,通过PHP的反射动态的获取类的方法、属性、参数等详细信息。用途:插件的设计,文档的自动生成,扩充PHP语言。class Person {const ...
  • 本文接上文“老生常谈反射之Class类的使用(必看篇)”,以编写一个用来获取类的信息(成员函数、成员变量、构造函数)的工具类来讲解"反射获取类的信息"1、获取成员函数信息/*** 获取成员函数信息* @param obj*/...
  • // 参数类型 if (paramType instanceof ParameterizedType)/**//* 如果是泛型类型 */{ Type[] types = ((ParameterizedType) paramType) .getActualTypeArguments();// 泛型类型列表 System.out.println(" Type...
  • 我正在尝试创建一个服务容器,并想知道如何反映调用该方法时使用的类型.见下文:public class ServiceContainer {HashMap services;public ServiceContainer() {services = new HashMap();}public void addService...
  • 对于任意一个类,都能够获取到这个类的所有属性和方法,对于任意 一个对象,都能够调用它的任意一个方法和属性(包括私有的方法和属性),这种动态 获取的信息以及动态调用对象的方法的功能就称为java语言的反射机制。...
  • 最简单的写法:创建四个接口A,B,C,D,每个接口中都声明了增删改查四个方法,完全一致public Map delete(HttpServletRequest request, User user);public Map query(HttpServletRequest request, User user, Map ...
  • 反射方法 public Object invokeMethod(Object owner, String methodName, Object[] args) throws Exception { Class ownerClass = owner.getClass(); Class[] argsClass = new Class[args.length]; for (int i = 0,...
  • 举个例子, 如上图中所示, 两种返回类型一种是List<T>, 一种是对象<T>时, 在写通用代码的时候应该怎么去处理 如果是List private Object doSelect(SlsSelect select, SlsTable table, Method ...
  • Java反射--获取方法的泛型返回或泛型参数 一.测试类 public class Test02 { public void parameterTest(Map<Integer, Dog> map){ } public Map<Integer,Dog> returnTest(){ return new ...
  • 由于 Java 泛型的类型参数之实际类型在编译时会被消除,所以无法在运行时得知其类型参数类型。package com.zhiming.tree;import java.lang.reflect.Method;import java.lang.reflect.ParameterizedType;import ...
  • 直接上代码//项目开始大量使用发射机制//从客户系统获取联系人信息String xmlStr = HttpUtil.doGet("http://xxxxxxx/api/listContact.action?clientid=1", null, "utf-8");Document document = null;ListcontactList...
  • @Testpublic void writeMethodDetail(){getMethodName...}/*** 通过反射获取某类下的方法名和参数名* @Description* @author zhangyd-c* @date 2015年10月26日 上午11:14:22* @param className*/public static void ...
  • Java反射获取泛型类型

    2021-02-12 11:45:06
    //getActualTypeArguments获取参数类型的数组,泛型可能有多个 Class c=(Class) p.getActualTypeArguments()[0]; System.out.println(c); } } 打印结果:classcom.test.Person ...
  • Java通过反射执行方法获取方法

    千次阅读 2021-03-22 17:06:28
    要动态获取一个对象方法的信息,首先需要通过下列方法之一创建一个 Method 类型的对象或者数组。getMethods()getMethods(String name,Class> …parameterTypes)getDeclaredMethods()getDeclaredMethods(String ...
  • 为了加深印象,特把方法都从新敲了一遍,等不会的时候返回了看看就好了。类ReflectionDemopackage Reflection;@Deprecatedpublic class ReflectionDemo {private String pri_field;public String pub_field;public ...
  • 此处用到了反射, 还有java.lang下的两个方法 java.lang.Package.isAnnotationPresent(Class<? extends Annotation> annotationClass) 如果指定类型的注释存在于此元素上,方法返回true j...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 172,672
精华内容 69,068
关键字:

反射获取方法参数类型