Java泛型与反射的综合应用

前一段时间,项目之余没有事情做,于是就学习了一下基础的泛型与反射。现记录如下:

首先,应当掌握的知识:

1)方法的动态参数:

不确定方法中参数的个数,就可以采用以下方法定义一个动态参数的方法

 示例:

public class testA {

  public static void parameters(String str,Object... objects ){
    System.out.println("以下是动态参数方法中的"+objects.length+"个参数");
    for(Object obj:objects){
      System.out.println("不定参数:"+obj);
    }
  }

  public static void main(String[] args) {
    parameters("中国人", "中国",1000,23.56f,"万里长城");
  }
}

结果:

  以下是动态参数方法中的4个参数
  不定参数:中国
  不定参数:1000
  不定参数:23.56
  不定参数:万里长城

2)泛型

泛型主要分为:泛型类、泛型接口、泛型方法

泛型类:

public class Message<T> {
  private T classes;

  public T getClasses() {
    return classes;
  }

  public void setClasses(T classes) {
    this.classes = classes;
  }
}

泛型方法:以下泛型泛型方法引用到上面的泛型类。

public static Message<?> genericMethod(){
  Message<Integer> msg =new Message<>();
  msg.setClasses(77);
  return msg;
}
public static void main(String[] args) {
  Message<?> msg=genericMethod();
  Object obj=msg.getClasses();
  System.out.println("类型:"+obj.getClass().getName()+";值为:"+obj);
}

结果:

类型:java.lang.Integer;值为:77

3)反射

使用反射可以得到一个类的方法以及类的参数

public class reflect {
  public String test1(){
    System.out.println("Test1");
    return "Test1";
  }
  public String test2(String st){
    System.out.println("Test2:"+st);
    return "Test2"+st;
  }
  public Float test3(Float fl){
    System.out.println("Test3:"+fl);
  return fl;
  }
  private String test4(Float fl,String st){
    System.out.println("Test4:"+fl);
    return st+" 4 "+fl;
  }

}

public static void main(String[] args) throws Exception {
  reflect ref = new reflect();
  Method[] methods =ref.getClass().getDeclaredMethods();
  for(Method method:methods){
    System.out.println("方法名:"+method);
  }
}

 使用getDeclaredMethods()方法可以得到所有的方法(不管私有公有方法),也可以getMethods()只得到公有方法

结果:

  方法名:public java.lang.String myproject.reflect.test1()
  方法名:public java.lang.String myproject.reflect.test2(java.lang.String)
  方法名:public java.lang.Float myproject.reflect.test3(java.lang.Float)
  方法名:private java.lang.String myproject.reflect.test4(java.lang.Float,java.lang.String)

执行其他类的方法,当执行其他类私有方法时,需要调用setAccessible(true)方法抑制Java的访问控制检查

public static void main(String[] args) throws Exception {
  reflect ref = new reflect();
  Method[] methods =ref.getClass().getMethods();
  Method m1=null;
  m1=ref.getClass().getDeclaredMethod("test4",Float.class,String.class);
  m1.setAccessible(true);
  Object bean = ref.getClass().newInstance();
  Object heInteger = m1.invoke(bean,23.45f,"hello,反射方法");
}

结果:

Test4:23.45

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

以上就是一些关于泛型,反射的基本知识,下面将综合利用这两个知识点,来创建一个方法:该方法的功能是可以调用任何类的方法,并返回该类的返回值以及返回值的类型。

1.泛型代码如下:

public class Message<T> {
  private T classes;

  public T getClasses() {
    return classes;
  }

  public void setClasses(T classes) {
    this.classes = classes;
  }
}

2.该方法代码如下:

public final class Generic {
  public static Message<?> hello(Object obj,String tag,Object...objects) throws Exception{
    Class<?> clazz=null;
    if(obj instanceof Class){
      clazz = (Class<?>)obj;
    } else{
      clazz = obj.getClass();
    }
    Method[] methods = clazz.getDeclaredMethods(); //获取该类文件的所有方法
    Method m1=null;
    for(Method method:methods){
      Class<?>[] classes =method.getParameterTypes();
      if(method.getName().equals(tag)){
        m1 = clazz.getDeclaredMethod(tag, classes);
        m1.setAccessible(true); // 抑制Java的访问控制检查
      }
    }
    Object bean = clazz.newInstance();
    Object heInteger = m1.invoke(bean,objects);
    Message<Object> msg =new Message<>();
    msg.setClasses(heInteger);
    return msg;
  }

}

3.要调用的类中的方法如下:

public class Haha {
  public String test1(){
    System.out.println("Test1");
    return "Test1";
  }
  public String test2(String st){
    System.out.println("Test2:"+st);
    return "Test2"+st;
  }
  public Float test3(Float fl){
    System.out.println("Test3:"+fl);
    return fl;
  }
  public String test4(Float fl,String st){
    System.out.println("Test4:"+fl);
    return st+" 4 "+fl;
  }

}

4.通过该方法调用上面类的方法:

public static void main(String[] args) throws Exception {
  Message<?> message =Generic.hello(new Haha2(),"test1",23.23f,"hahaaaaaaa");
  message.getClasses();
  System.out.println("返回值类型:"+message.getClasses().getClass().getName()+";返回值:"+message.getClasses());
}

结果:

Test1:23.23
返回值类型:java.lang.String;返回值:hahaaaaaaa 4 23.23

 

posted @ 2018-01-18 23:30  井井凉风  阅读(451)  评论(0编辑  收藏  举报