• 初识Java反射机制


    1.ClassLoader的类加载机制:并非一次性加载,而是需要的时候加载(运行期间动态加载)(Class文件加载到内存的代码段),static语句块在加载后执行一次。dynamic语句块(就是一个语句块,用大括号括起来)每次new新的对象都会执行,等同于构造方法中的语句,只不过加载到构造方法之前,用的较少。

    注意参数的大小写,也不要多加空格。

    看下面这个例子:

     1 public class Dynamic {
     2 
     3     public static void main(String[] args) {
     4         new A();//不是一次性加载,从结果看出这个分割线的位置
     5         System.out.println("___________________");
     6         new B();
     7         
     8         new C();
     9         new C();
    10         
    11         new D();
    12         new D();
    13     }
    14 
    15 }
    16 
    17 class A {
    18     
    19 }
    20 
    21 class B {
    22     
    23 }
    24 
    25 class C {
    26     static {
    27         System.out.println("——————————————静态类加载——————————————");
    28     }
    29 }
    30 
    31 class D {
    32     {
    33         System.out.println("************动态类加载***********");
    34     }
    35 }

    下面是未加-verbose:class的结果:

    ___________________
    ——————————————静态类加载——————————————
    ************动态类加载***********
    ************动态类加载***********
    

    下面是加参数后的结果:

    2.verbose:冗长的详细的

    3.JDK里的类加载器很多。
    4.bootstrap:启动节点,引导节点。

     1 public class TestJDKClassLoader {
     2 
     3     public static void main(String[] args) {
     4         System.out.println(String.class.getClassLoader());
     5         //System.out.println(com.sum.crypto.provider.DESKeyFactory.class.getClassLoader().getClass().getName());
     6         System.out.println(TestJDKClassLoader.class.getClassLoader());
     7         System.out.println(ClassLoader.getSystemClassLoader());
     8     }
     9 
    10 }
    null
    sun.misc.Launcher$AppClassLoader@45a1472d
    sun.misc.Launcher$AppClassLoader@45a1472d
    

    5.ClassLoader类在java.lang包里

     1 public class TestJDKClassLoader {
     2 
     3     //getClass可以获取一个类的定义信息,然后使用反射去访问其全部信息(包括函数和字段)
     4     public static void main(String[] args) {
     5         ClassLoader c = TestJDKClassLoader.class.getClassLoader();
     6         while(null!=c) {
     7             System.out.println(c.getClass().getName());
     8             //虽然叫parent但并不是继承
     9             c = c.getParent();
    10         }
    11     }
    12 
    13 }
    sun.misc.Launcher$AppClassLoader
    sun.misc.Launcher$ExtClassLoader
    

    6.对象.getClass相当于类名.class。

    7.properties文件

       参考资料:http://blog.csdn.net/netwarning/article/details/1569900

      properties文件顾名思义就是属性文件,可以在它里面定义一些字段,这将不需要我们在代码中书写,这些信息从代码中分离出来了。看下面的例子:

      注意在文件里面就不需要加分号。

     1 //文件名为myProperties.properties
     2 
     3 String driver = "com.mysql.jdbc.Driver"
     4 String url = "jdbc:mysql://localhost/myDB";
     5 String name = "root"
     6 String password = "123"
     7 
     8 //***************************
     9 Class.forName(driver);
    10 Connection con = DriverManager.getConnection(url,name,password);
    11 
    12 //**************************
    13 String driver; 
    14 String url;
    15 String name; 
    16 String password; 
    17 
    18 FileInputStream fis = new FileInputStream(myProperties.properties);
    19 Properties properties = new Properties();
    20 properties.load(fis);            //从输入流中读取属性文件的内容
    21 fis.close();
    22 //从属性文件中读取相应字段的信息
    23 driver = properties.getProperty(driver);
    24 url = properties.getProperty(url);
    25 name = properties.getProperty(name);
    26 password = properties.getProperty(password);
    27 
    28 Class.forName(driver);
    29 Connection con = DriverManager.getConnection(url,name,password);
    30 
    31 /*
    32 我们看到数值和代码已经分离,这样很方便我们修改数值!
    33 再有一定要注意properties文件中的字段的写法,不要再多添“”否则会出现问题!
    34 因为getProperty()方法返回的是一个字符串!
    35 
    36 我想应该再对这个文件做一下加密处理会更好一些是吧? 
    37 */

      8.Java语言不够动态,真正动态的语言是JS、Ruby和Python。
      9.java的反射机制很重要,是学习SSH的基础以及面向切面编程Aspect Oriented Programming(AOP)。
      10.RC就是Release Candidate(候选版本)的简称。从微软的惯例来看OS的开发步骤是这样的:内部测试->alpha公测->beta公测->RC版->正式版上市。
      11.下面是反射机制的例子:

     1 package a;
     2 
     3 import java.lang.reflect.Method;
     4 
     5 /*
     6  * properties文件里只有class=T,注意没有问号
     7  * 实现了代码和数据的分离,这样不必写死
     8  * 问题:知道类名字,然后new出来一个
     9  */
    10 
    11 //学习SSH时类的名字很多时候都是在配置文件里的
    12 public class TestReflection {
    13 
    14     public static void main(String[] args) throws Exception {
    15         /*
    16          * 使用new创建一个类的时候,这个类可以没有被加载。
    17          * 但是使用newInstance()方法的时候,
    18          * 就必须保证这个类已加载且类已经连接了。
    19          */
    20         String str = "a.T";//到时候这个换成从文件里读取,靠,必须写完整路径
    21     
    22         Class c = Class.forName(str);//加载类
    23         /*
    24          * newInstance和new的区别在于一个方法一个关键字
    25          * 且前者要求类已经加载了才可实例化
    26          */
    27         Object obj = c.newInstance();
    28         Method[] methods = c.getMethods();
    29         for(Method m: methods) {
    30             //System.out.println(m.getName());
    31             if(m.getName().equals("myMehtod")) {
    32                 //不能是c或者T.class,因为方法
    33                 /*
    34                  * invoke方法是可变参数的方法,传递0个或者多个参数
    35                  * 主要是因为不知道传递几个参数
    36                  */
    37                 m.invoke(obj,2);//必须是obj,不能是c,方法的调用是对象
    38                 for(Class paramType : m.getParameterTypes()) {
    39                     System.out.println(paramType.getName());
    40                 }
    41             }
    42             
    43             if(m.getName().equals("getS")) {
    44                 Class returnType = m.getReturnType();
    45                 System.out.println(returnType.getName());
    46             }
    47         }
    48         
    49     }
    50 
    51 }
    52 
    53 class T {
    54     //static块的用法http://www.cnblogs.com/hxsyl/archive/2013/04/16/3024953.html
    55     static {//类加载时执行
    56         System.out.println("T loaded");//就是为了证明类已经加载
    57     }
    58     
    59     public T() {
    60         System.out.println("T constructed");
    61     }
    62     
    63     int i;
    64     String s;
    65     
    66     public void myMehtod(int i) {
    67         this.i = i;
    68         System.out.println("方法调用");
    69     }
    70     
    71     public String getS() {
    72         return s;
    73     }
    74 }

       12.理解invoke方法

     1 package a;
     2 
     3 /*
     4  * 下面这个是网上的代码,找了好久还就这一个
     5  * 看了也还是没明白invoke方法
     6  */
     7 import java.lang.reflect.Method;
     8 
     9 public class InvokeTester {
    10 
    11     public int add(int param1, int param2) {
    12         return param1 + param2;
    13     }
    14 
    15     public String echo(String msg) {
    16         return "echo:" + msg;
    17     }
    18 
    19     public static void main(String[] args) throws Exception {
    20         Class classType = InvokeTester.class;
    21         Object invokertester = classType.newInstance();
    22 
    23         Method addMethod = classType.getMethod("add", new Class[] { int.class,
    24                 int.class });
    25         // Method类的invoke(Object obj,Object args[])方法接收的参数必须为对象,
    26         // 如果参数为基本类型数据,必须转换为相应的包装类型的对象。invoke()方法的返回值总是对象,
    27         // 如果实际被调用的方法的返回类型是基本类型数据,那么invoke()方法会把它转换为相应的包装类型的对象,
    28         // 再将其返回
    29         Object result = addMethod.invoke(invokertester, new Object[] {
    30                 new Integer(100), new Integer(200) });
    31         // 在jdk5.0中有了装箱 拆箱机制 new Integer(100)可以用100来代替,系统会自动在int 和integer之间转换
    32         System.out.println(result);
    33 
    34         Method echoMethod = classType.getMethod("echo",
    35                 new Class[] { String.class });
    36         result = echoMethod.invoke(invokertester, new Object[] { "hello" });
    37         System.out.println(result);
    38     }
    39 }

      13.java的反射机制会破坏单例模式……

  • 相关阅读:
    我的20130220日 在北京 do{ Web Develop } while(!die)
    关于NVelocity模板引擎初学总结
    C# 23种设计模式汇总
    基于模型的设备故障检测
    图像去噪之光斑去除
    虹膜识别
    封闭曲线拟合
    基于故障树的系统可靠性分析
    图像识别之棋子识别
    时间序列的模式距离
  • 原文地址:https://www.cnblogs.com/hxsyl/p/3163893.html
Copyright © 2020-2023  润新知