精华内容
下载资源
问答
  • 利用java反射原理调用方法时,常先需要传入方法参数数组才能取得方法。该方法参数数组采用动态取得的方式比较合适
  • //获取方法的参数类型。 for(Type paramType:type){ System.out.println("#"+paramType); //ParameterizedType:参数化类型,判断是否是参数化类型。 if(paramType instanceof ParameterizedType){ //...
    package com.buaa.reflectTest;
    
    import java.lang.reflect.Method;
    import java.lang.reflect.ParameterizedType;
    import java.lang.reflect.Type;
    import java.util.List;
    import java.util.Map;
    
    public class Demo02 {
    	public void test01(Map<String,User> map,List<User> list,int id){
    		System.out.println("Demo02.test01");
    	}
    	
    	public Map<Integer,User> test02(){
    		System.out.println("Demo02.test02");
    		return null;
    	}
    	
    	public void test03(int a,String s){
    		System.out.println("Demo02.test03");
    	}
    	
    	public static void main(String[] args) throws Exception {
    		Method m = Demo02.class.getDeclaredMethod("test01", Map.class,List.class,int.class);
    		Type[] type = m.getGenericParameterTypes();//获取方法的参数类型。
    		for(Type paramType:type){
    			System.out.println("#"+paramType);
    			//ParameterizedType:参数化类型,判断是否是参数化类型。
    			if(paramType instanceof ParameterizedType){
    				//获得源码中的真正的参数类型
    				Type[] genericType = ((ParameterizedType)paramType).getActualTypeArguments();
    				for(Type gt:genericType){
    					System.out.println("泛型类型:"+gt);
    				}
    					
    			}
    			
    		}
    		
    		System.out.println("###########。。华丽的分隔线。。############");
    		
    		Method method = Demo02.class.getDeclaredMethod("test02");
    		Type t = method.getGenericReturnType();//获取返回值类型。
    		System.out.println("#"+t);
    		if(t instanceof ParameterizedType){
    			Type[] genericType = ((ParameterizedType)t).getActualTypeArguments();
    			for(Type gt:genericType){
    				System.out.println("泛型类型:"+gt);
    			}
    				
    		}
    			
    		
    	}
    }
    

    展开全文
  • 在自定义mybatis框架的过程中,在使用注解来进行配置sql语句时,就遇到了一些关于获取返回值类型的小问题。比如说方法 publIc User getOne(int id);的返回值类型是User;public List< User > getAll();的...

    最近在学mybatis的时候,自己根据参考资料自定义了一个简单的mybatis框架,期望能够简单实现对数据库操作的增删查改功能。在自定义mybatis框架的过程中,在使用注解来进行配置sql语句时,就遇到了一些关于获取返回值类型的小问题。比如说方法 publIc User getOne(int id);的返回值类型是User;public List< User > getAll();的返回值类型是List< User >,但是我们在进行mybatis框架书的时候,通过注解配置时,我们获取的返回值类型需要获取的是实体类的全限定类名,也即是我们实际上需要获取的是 List< User >中的实体类User即可。在我们实际的应用中,为了便于代码的通用性以及复用性,我们习惯使用泛型,比如public List< T> getAll()和public Map<T,V> getAll();这两个方法,就是使用了泛型,是代码更加通用。那么我们首先来了解一下泛型的原理:
    定义:把类型明确的工作推迟到创建对象或调用方法的时候才去明确的特殊的类型。
    Java泛型设计原则:只要在编译时期没有出现警告,那么运行时期就不会出现ClassCastException异常.
    参数化类型:把类型当作是参数—样传递;<数据类型>只能是引用类型。
    相关术语:
    List< E >中的E称为类型参数变量。
    List< Integer >中的Integer称为实际类型参数。
    整个称为List< E >泛型类型。
    整个List< Integer >称为参数化的类型ParameterizedType。

    不过也就是因为使用了泛型,导致我们在通过反射获取返回值了类型的时候会更加麻烦一些。为了更加方便学习通过反射获取返回值类型以及参数化的实际参数类型,我特意写了几个小案例进行测试讲解。
    1.首先创建用于测试的各个类,在这些类中我们不需要写额外的代码实现,只是用于测试获取返回值类型即可。

    package dao;
    
    import java.util.List;
    
    import entity.User;
    
    /**
     * @author 陌意随影
     TODO :UserDao测试接口
     *2020年7月26日  下午10:58:04
     */
    public interface UserDao {
     
    /**
     * 获取所有用户
     * @return 返回所有用户的集合
     */
    	public List<User> getAll();
    /**
     * 通过指定的id获取一个用户对象
     * @param id: 指定的id
     * @return 返回一个User
     */
    	public User getOne(int id);
    
    }
    
    
    package dao;
    
    import java.util.Map;
    
    /**
     * @author 陌意随影
     TODO :学生dao测试类
     *2020年7月26日  下午11:02:10
     */
    public interface StudentDao<T,V> {
    	/**
    	 * 获取所有对象
    	 * @return 返回一个map
    	 */
    	public Map<T,V> getAll();
    	/**
    	 * 获取一个T对象
    	 * @return 返回T
    	 */
    	public T getT();
    	/**
    	 * 获取一个V对象
    	 * @return 返回V
    	 */
    	public	V getV();
    
    }
    
    
    package entity;
    
    /**
     * @author 陌意随影
     TODO :测试实体类
     *2020年7月26日  下午11:05:27
     */
    public class Cat {
    
    }
    
    
    package entity;
    
    /**
     * @author 陌意随影
     TODO :测试实体类
     *2020年7月26日  下午11:05:10
     */
    public class Dog {
    
    }
    
    
    package entity;
    
    /**
     * @author 陌意随影
     TODO :测试用户类
     *2020年7月26日  下午10:59:22
     */
    public class User {
    
    }
    
    

    然后建立相关的测试类:

    package test;
    
    
    import org.junit.jupiter.api.Test;
    
    class StudentDaoTest {
    
    	@Test
    	void testGetAll() {
    	}
    
    	@Test
    	void testGetT() {
    	}
    
    	@Test
    	void testGetV() {
    	}
    
    }
    
    
    package test;
    
    
    import org.junit.jupiter.api.Test;
    
    class UserDaoTest {
    
    	@Test
    	void testGetAll() {
    		
    	}
    
    	@Test
    	void testGetOne() {
    	}
    
    }
    
    

    这些类的具体目录结构为:
    在这里插入图片描述
    2.建立测试类进行测试
    2.1首先测试UserDao接口

    package test;
    
    
    import java.lang.reflect.Method;
    import java.lang.reflect.ParameterizedType;
    import java.lang.reflect.Type;
    import org.junit.jupiter.api.Test;
    
    class UserDaoTest {
    
    	@Test
    	void test() throws Exception {
    	 //根据UserDao接口的全限定类名通过反射获取该接口的字节码
    	Class<?> userDaoClass = Class.forName("dao.UserDao");
    	//获取UserDao所有的方法
    	Method[] methods = userDaoClass.getMethods();
    	for(Method method: methods) {
    		//获取方法的名称
    		String methodName = method.getName();
    		//判断是否是UserDao中的getAll()或者getOne(int id)方法,
    		if(methodName.startsWith("get")) {
    			//返回一个Type对象,表示由该方法对象表示的方法的正式返回类型。
    			//比如public List<User> getAll();那么返回的是List<User>
    		  Type genericReturnType = method.getGenericReturnType();
    		  //获取实际返回的参数名
    		  String returnTypeName = genericReturnType.getTypeName();
    		  System.out.println(methodName+"的返回参数是:"+returnTypeName);
    		  //判断是否是参数化类型
    		  if(genericReturnType instanceof ParameterizedType) {
    			  //如果是参数化类型,则强转
    			  ParameterizedType parameterizedType = (ParameterizedType) genericReturnType;
    			//获取实际参数类型数组,比如List<User>,则获取的是数组[User],Map<User,String> 则获取的是数组[User,String]
    			  Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
    			  for(Type type:actualTypeArguments) {
    				  //强转
    				  Class<?> actualTypeArgument = (Class<?>) type;
    				 //获取实际参数的类名
    				  String name = actualTypeArgument.getName();
    				  System.out.println(methodName+"的返回值类型是参数化类型,其类型为:"+name);
    			  }
    			  
    		  }else {
    			  //不是参数化类型,直接获取返回值类型
    			  Class<?> returnType = method.getReturnType();
                  //获取返回值类型的类名
    			  String name = returnType.getName();
    			  System.out.println(methodName+"的返回值类型不是参数化类型其类型为:"+name);
    			  
    		  }
    		  
    		}
    		
    		
    	}
    	}
    
    
    }
    
    

    从该测试类中我们可以看到,我们首先获取对应的方法后,使用

    //比如public List<User> getAll();那么返回的是List<User>
    Type genericReturnType = method.getGenericReturnType();
    

    来获取方法的正式返回类型,比如public List< User > getAll();那么返回的是List< User >,public Map< String,User> getAll();那么返回的是Map< String,User>;,然后判断是否是参数化类型,在这里多说一句,其实参数化类型就是我们常见的List< User >,Map< String,Integer>等这些 < > 中的参数,我们可以通过是否有< >来判断是不是参数化。当我们知道是参数化类型后,需要进行强转:

     ParameterizedType parameterizedType = (ParameterizedType) genericReturnType;
    
    

    2.2下面我们开始对ParameterizedType进行解析:

    public interface ParameterizedType extends Type {
        Type[] getActualTypeArguments();
    
        Type getRawType();
    
        Type getOwnerType();
    }
    

    2.2.1 Type[] getActualTypeArguments​():返回一个Type对象的数组,表示此类型的实际类型参数。
    请注意,在某些情况下,返回的数组为空。 如果此类型表示嵌套在参数化类型中的非参数化类型,则可能会发生这种情况。
    结果:一个 Type对象的数组,表示此类型的实际类型参数。
    2.2.2 Type getRawType​():返回表示此类型的类或接口的 Type对象。
    结果 :表示声明此类型的类或接口的 Type对象 。
    2.2.3Type getOwnerType():返回表示此类型Type成员的类型的Type对象。 例如,如果该类型是O< T >.I < S > ,返回的表示O< T > 。
    如果此类型是顶级类型,则返回null 。
    结果 :表示此类型Type成员的类型的Type对象。 如果此类型是顶级类型,则返回null。
    2.3获取返回类型的实际参数数组:

      Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
    
    

    2.4将actualTypeArguments 每个Type强转为Class后获取其方法名,也就是获取参数类型的全限定类名,如Map<User,Integer>中的实际参数数组actualTypeArguments ={User,Integer},其全限定类名对应为{dao.User , java.lang.Integer }。

    2.5如果不是参数化类型的话,可直接获取返回值类型然后获取返回值类型的全限定类名:

     //不是参数化类型,直接获取返回值类型
    			  Class<?> returnType = method.getReturnType();
                  //获取返回值类型的类名
    			  String name = returnType.getName();
    

    2.6测试的结果为:
    在这里插入图片描述
    我们发现 public List< User > getAll();的返回值类型是参数化类型,为List< User >,其全限定类名表示为:java.util.List<entity.User>
    public User getOne(int id);的返回值类型为User ,不是参数化类型,其全限定类名表示为:entity.User。
    由此我们初步懂得了如何获取简单的参数化类型的返回值。那么对于更加复杂的泛型类的如Map<T,V>的实际参数该怎么获取呢?欲知后事如何请看
    Java通过反射获方法的返回值的类型以及参数化的实际类型(下篇)

    该测试的源代码已经上传到我的个人博客,如有需要移步到我的个人博客里并下拉到文章结束底部点击链接下载源码:http://moyisuiying.com/index.php/javastudy/170.html

    展开全文
  • 2.此时切入点方法的参数类型为 int ,则在反射获取方法对象时就会因为参数类型对不上而获取失败 3.解决方法很简单的就是把切入点方法的基本类型参数改为包装类,即可在反射中正确获取方法对象 ...

    1.在获取参数列表时获取的是参数的class对象
    则如 int 类型参数 获取出来的是 Integer包装类对象
    在这里插入图片描述

    2.此时切入点方法的参数类型为 int ,则在反射获取方法对象时就会因为参数类型对不上而获取失败
    在这里插入图片描述
    3.解决方法很简单的就是把切入点方法的基本类型参数改为包装类,即可在反射中正确获取方法对象
    在这里插入图片描述

    展开全文
  • 通过反射获取参数名称

    千次阅读 2019-05-07 23:46:10
    通过反射,可以获取到方法的参数类型,返回值类型,方法名称,这些大家应该都清楚,但是能够获取得到参数名称吗?在spring中,通常通过参数名称进行参数匹配并赋值。 在JDK1.7版本及以下,我们可以借助于Spring中的...

    通过反射,可以获取到方法的参数类型,返回值类型,方法名称,这些大家应该都清楚,但是能够获取得到参数名称吗?在spring中,通常通过参数名称进行参数匹配并赋值。

    在JDK1.7版本及以下,我们可以借助于Spring中的类LocalVariableTableParameterNameDiscoverer,来获取得到参数名称。需要注意的是,该方法似乎只对类的方法有效,针对接口的方法无效。

    使用如下:

    package com.company.test;
    
    import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
    
    import java.lang.reflect.Method;
    import java.util.Arrays;
    
    public class MethodParameterName {
    
        public void getInfo(String name, Integer age) {
        }
    
        public static void main(String[] args) {
            LocalVariableTableParameterNameDiscoverer discoverer = new LocalVariableTableParameterNameDiscoverer();
            Class<?> clazz = MethodParameterName.class;
            Method[] methods = clazz.getDeclaredMethods();
            for (Method method : methods) {
                System.out.println("方法名称:" + method.getName());
                String[] parameterNames = discoverer.getParameterNames(method);
                if (parameterNames != null) {
                    Arrays.asList(parameterNames).forEach(item -> System.out.println("方法参数名称:" + item));
                }
            }
        }
    }
    

    如果是在JDK1.8,我们又多了一种方法,JDK1.8中新增了

     

    展开全文
  • 笔者最近在学习mybatis的框架,在写源码的时候遇到了一些关于通过反射获取返回值类型的实际参数类型的问题,并且已经写有一篇关于简单的返回值类型的获取,诸如public User getOne(int id);获取返回值的类型是User,...
  • 反射获取方法参数与返回值类型

    千次阅读 2012-07-26 15:30:22
     参数类型 21   if  (paramType  instanceof  ParameterizedType) /**/ /*  如果是泛型类型  */ { 22  Type[] types  =  ((ParameterizedType) paramType) 23  .getActualTypeArguments(); //...
  •  一般来说,通过反射是很难获得参数名的,只能取到参数类型,因为在编译时,参数名有可能是会改变的,需要在编译时加入参数才不会改变。  使用注解是可以实现取类型名(或者叫注解名)的,但是要写注解,并不方便...
  • 反射(Reflection)是.NET中的重要机制,通过放射,可以在运行时获得.NET中每一个类型(包括类、结构、委托、接口和枚举等)的成员,包括方法、属性、事件,以及构造函数等。还可以获得每个成员的名称、限定符和参数...
  • 主要介绍了详解java中反射机制(含数组参数)的相关资料,希望通过本文能帮助到大家,让大家理解掌握这部分内容,需要的朋友可以参考下
  • Java-使用反射获取类型信息

    千次阅读 2018-09-18 19:30:33
    Java中如何使用反射获取类型信息?Java中如何使用反射获取类型信息?一个简单类的例子分析如何获取不同属性的类型1、普通类型2、数组类型3、带泛型的类型4、复杂的嵌套类型5、多个泛型参数总结 Java中如何使用反射...
  • ParameterizedType是一个接口,这个类可以用来检验泛型是否被参数化 比如: [java] view plain copy class Dao  {   public Dao(){     }  }  上面的这个类,也...
  • Java反射获取实际泛型类型参数

    千次阅读 2016-03-14 10:53:49
    反射的主要作用是能够在运行时获取一个Class的各个元素的结构,但无法更改这些元素的结构。这些元素就是前面说的成员变量和成员方法,并且对于成员变量,反射可以对其进行设值和取值,对于成员方法,反射可以直接...
  • java反射提供了很多方法,获取所有的方法,获取所有的参数类型等,但是却没有一个方法能够帮助我们获取方法的参数名列表。 首先: 为什么我们需要获取到方法对应的参数名称? 原因是例如mybatis的mapper接口中...
  • 但使用中遇到了一个问题,接口定义的方法只有一个“T”参数,反射method.getParameterTypes()却得到两个参数类型,请问各位大牛java内部的实现方式是怎样的? 另外,使用jdk1.8时还会出现反射后的两个参数...
  • Springboot AOP利用反射获取请求参数

    千次阅读 2019-09-10 17:45:37
      我们在某些业务场景下需要对接口的入参进行校验或者权限验证,因此需要获取接口的参数列表依次来支持我们的逻辑操作,因此需要我们获取接口的参数,下面是利用自定义注解配合Aop来实现的一个思路: 正常: ...
  • 利用反射机制动态获取对象属性名称及数据类型 利用反射机制动态获取对象属性名称及数据类型 利用反射机制动态获取对象属性名称及数据类型 利用反射机制动态获取对象属性名称及数据类型 利用反射机制动态获取对象属性...
  • java8反射获取方法的参数名称 文章目录java8反射获取方法的参数名称1.简要说明2.java类获取方法参数名称测试代码解决方法执行结果3.接口测试代码执行结果解决方法感谢 1.简要说明 演示springboot版本为2.0.3....
  • java 反射 调用私有方法(有参数私有方法)获取私有属性值
  • java反射获取方法参数及返回值类型

    千次阅读 2013-09-08 15:38:48
    // 参数类型 if (paramType instanceof ParameterizedType)/**//* 如果是泛型类型 */{ Type[] types = ((ParameterizedType) paramType) .getActualTypeArguments();// 泛型类型列表 System.out.println(" Type...
  • 一般来说,通过反射是很难获得参数名的,只能取到参数类型,因为在编译时,参数名有可能是会改变的,需要在编译时加入参数才不会改变。 使用注解是可以实现取类型名(或者叫注解名)的,但是要写注解,并不方便。 ...
  • java通过反射获取到list泛型的类型

    千次阅读 2020-12-27 20:11:33
    Field[] fields = bean.getClass().getDeclaredFields(); for(Field f : fields){ ... // 如果是List类型,得到其Generic的类型 Type genericType = f.getGenericType(); if(genericType == null) continue;
  • 目录 介绍 概念化这个混乱 编码此混乱 下载实用程序-5.7 KB 介绍 ...通过这个技巧,我将努力向读者展示如何使用反射来查询一个集合类的元素类型。...有时我们可能需要通过反射获取集合的元素类型。我通
  • 一、反射获取类型对象与值 package main import ( "fmt" "reflect" ) func main() { a := 36 atype := reflect.TypeOf(a) fmt.Println(atype.Name()) //获取类型名称为int avalue := reflect.ValueOf(a) ...
  • 在某些时候,我们可能需要反射技术来获取其方法来使用它,但是方法名,方法的参数可能全都不知道 传入的参数具体是什么我们也不知道 例如,在使用切面的时候, ProceedingJoinPoint种getArgs也只是一个Object数组...
  • Java——通过反射获取函数参数名称

    万次阅读 2017-04-30 22:53:28
    通过javassit获取参见 http://blog.csdn.net/viviju1989/article/details/8529453 这篇文章的方法一,实现比较麻烦,就不说了。通过spring的LocalVariableTableParameterNameDiscovererpublic static List<String> ...
  • 我想用Object接受参数,然后在方法里反射获得传进来的具体类型,怎麼操作?
  • 一、反射的作用 1、反编译:从.class文件到.java文件。 2、通过反射机制访问java类的属性,方法,构造方法等。 创建一个普通类: class User{ String name; User(){} ...二、获取Class类...
  • 听到这个问题我是懵逼的,之前只知道通过反射可以获取方法名,形参的类型,但是从来没有注意可不可以获取方法形参的名称。在网上查了一些资料之后,知道在jdk1.7之前获取方法中形参的名称的是打印arg0类型。但是在...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 163,964
精华内容 65,585
关键字:

反射获取参数类型