JAVA反射使用实例和class.getResource()得到URL中含有中文和空格乱码问题

    技术2022-05-20  28

    JAVA反射使用实例

    package invoke;

    import java.lang.reflect.Method;

    public class T1 {  public static void main(String[] args) throws Exception {   // 1.普通方法反射--invoke.T3类全路径   // new Class[]{String.class,String.class}等同String.class, String.class   Method method = Class.forName("invoke.T3").getMethod("toStr",     String.class, String.class);

      // new Object[]{"123","456"}等同"123", "456"   Object o = method.invoke(T3.class.newInstance(), "123", "456");   System.out.println("return:" + o.toString());   // 直接调用   T3.class.newInstance().toStr("aaaaaaaa", "bbbb");

      // 1.带数组的方法反射   Method method1 = Class.forName("invoke.T3").getMethod("toStr",     String[].class, int.class);   Object obj = method1.invoke(T3.class.newInstance(), new String[] {     "aa", "bb" }, 99);   System.out.println("method1 return:" + obj);

      Method method2 = Class.forName("invoke.T3").getMethod("toStr",     new Class[] { String[].class, int.class });   method2.invoke(T3.class.newInstance(), new Object[] {     new String[] { "cc", "dd" }, 999 });

      Method[] ms = Class.forName("invoke.T3").getMethods();   for (Method method3 : ms) {    System.out.println("method name:" + method3.getName());    if (method3.getName().equals("toStr")) {     method3.invoke(T3.class.newInstance(), "123", "456");    }   }  } }

    class T3 {  public T3() {   System.out.println("**T3()***");  }

     public String toStr(String s, String s1) {   System.out.println(s + s1);   return s + s1;  }

     public String toStr(String[] ss, int i) {   StringBuffer sb = new StringBuffer();   for (int j = 0; j < ss.length; j++) {    sb.append(" " + ss[j]);   }   System.out.print("String[]:" + sb.toString() + " i:" + i);

      return sb.append(i).toString();  } }

     

    得到有参数构造方法的对象实例. 1.如T3有这样的构造器 public T3(int id,String name,String password) 2.得到实例--通过有参构造器得到 T3 t3=T3.class.getConstructor(int.class,String.class,String.class).newInstance(1,"admin","admin");

    getMethod(String name, Class<?>... parameterTypes) 返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。--这个只能得到公共方法. getDeclaredMethod(String name, Class<?>... parameterTypes) 返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。--这个可以得到所有定义的方法. 通过反射调用私用方法时要加上mothod.setAccessible(true); 其它得到字段/构造器/类等也是一样的.

     

    以下内容转自:http://blog.csdn.net/heshuanxu/article/details/7661424

    射的基石——Class

    如何得到字节码文件的实例对象?

    有三种方式:

    类名.class 如:System.class

    对象.getClass() 如:new Date().getClass();

    Class.forName(" 类名") 如:Class.forName(" java.util.Date");

    代码:

    package com.hncu.day1;

    import java.util.Date;

    public class GetClass  {

     public static void main(String[] args) throws Exception{   Class c1 = Date.class;//Date类的字节码文件 他是一个Class类型的实例对象,   GetClass gc = new GetClass();   gc.getClass();      System.out.println(gc.getClass());   System.out.println(c1);   System.out.println(Class.forName("com.hncu.day1.GetClass"));  }

    }

     

    数组类型的Class实例对象:

    Class.isArray();

    System.out.println(int[].class.isArray());//true

    反射:

    就是把java中的各种成分映射成相应的java类。

    一个类中的组成成分:成员变量,方法,构造方法,包等信息,也用一个个的java类来表示。

    一个类中的的每个成员都已用相应的反射API类的一个实力对象来表示,通过调用Class累的方法可以得到这些实例对象后,得到实例对象后怎么用是学习反射的要点.

    Constructor类代表某个类的一个构造方法。

    得到某个类的所有构造方法:

    Constructor[] constructor = Class.forName("java.lang.String").getConstructor();

    得到某一个构造方法:

    Constructor constructor = Class.forName("java.lang.String").getConstructor(StringBuffer.class);//得到StringBuffer类的构造函数

    实例对象:

    普通方式:String str = new String( new StringBuffer("abc"));

    反射方式:

    Constructor constructor = String.class.getConstructor(StringBuffer.class);

    String str = (String)constructor.newInstance(new StringBuffer("abc"));

    Filed 

    Filed 类代表某个类中的一个成员变量。

     

    import java.lang.reflect.Field;

    public class ReflectDemo {  private int x;  public int y;

     public ReflectDemo(int x, int y) {   this.x = x;   this.y = y;  }

     public static void main(String[] args) throws Exception {   ReflectDemo rd = new ReflectDemo(3, 8);   ReflectDemo rd1 = new ReflectDemo(4, 9);      Field fieldX = rd.getClass().getDeclaredField("x");// 得到类中私有x的定义。   Field fieldY = rd.getClass().getField("y");// 得到类中y的定义。

      System.out.println(fieldY.get(rd));// 得到rd对象y的值   System.out.println(fieldY.get(rd1));// 得到rd1对象的y值

         fieldX.setAccessible(true);// 将fieldX设置为可见。   System.out.println(fieldX.get(rd));// 得到rd对象中x的值  } }

     

    利用反射获取String 类型的成员变量后,修改字符串中的字符。

    import java.lang.reflect.Field;

    public class ReflectDemo {

     Private String str1 = "reflect";  Private String str2 = "reflectdemo";

     public static void main(String[] args) throws Exception {

      ReflectDemo rd = new ReflectDemo();   changeValue(rd);  }

     private static void changeValue(Object obj) throws Exception {   Field[] fields = obj.getClass().getDeclaredFields();//获取所有定义的成员变量   for (Field field : fields) {    if (field.getType() == String.class) {// 字节码使用== 使用的是一份字节码     String oldValue = (String) field.get(obj);     String newValue = oldValue.replace('r', 'R');     field.set(obj, newValue);    }   }   System.out.println(obj);  }

     // 重写toString方法  public String toString() {   return str1 + " " + str2;  } }

     

    Method

    代表某个类中的一个成员方法

    得到类中的一个方法:

    :Class.forName("java.lang.String").getMethod("charAt",int.class)

    调用方法:

    ü 普通方式:

    str对象来调用,str.charAt(1);

    ü 反射方式:

    Method m =String.class.getMethod("charAt"int.class);

    System.out.println(m.invoke(str1, 1));//为str1这个对象调用charAt方法参数为1,打印“r”,Str1 这个对象要用静态修饰。

    如果invoke方法的第一个参数为null ,表示该Method对象对应的是一个静态方法。

     

     

    (重点理解)接受数组参数的成员方法进行反射:

    import java.lang.reflect.Method;

     public class ReflectDemo2 {

     public static void main(String[] args) throws Exception {   String startClassName = args[0];   Method mainMethod = Class.forName(startClassName).getMethod("main", String[].class);   mainMethod.invoke(null,new Object[]{new String[]{"hncu","nihao"}});   //ReflectTest.maint(new String[]{"dkj","kdfj"});     }

    }   class ReflectTest {   public static void main(String[] args) {    for(String s : args) {     System.out.println(s);    }   }  }

     

    打印结果:

    hncu nihao

     

    解决通过this.class.getResource()得到的URL中含有中文和空格乱码问题

     ClassLoader的getResource方法使用了utf-8对路径信息进行了编码,当路径中存在中文和空格时,他会对这些字符进行转换,这样,得到的往往不是我们想要的真实路径,在此,调用了URLDecoder的decode方法进行解码,以便得到原始的中文及空格路径

    例如:结果是file:/C:/Documents and Settings/庄晓毅     /Local Settings/Temp/temp0.jar!/db/dmozdata.mdb  

    而我们期望是 C:/Documents andsettigsd sdfsdfsdf sdfsdf sdfsd 等等

    这里我们只要在获取到的例如: String configPath = this.getClass().getClassLoader().getResource("allowPath.xml").getFile();

    把返回前decode下就可以了. 用utf-8编码. 

    Java代码 configPath = java.net.URLDecoder.decode(configPath,"utf-8");  


    最新回复(0)