博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java反射(2)+Class.forName( )
阅读量:2182 次
发布时间:2019-05-01

本文共 5096 字,大约阅读时间需要 16 分钟。

在上一篇文章中说说java反射(1)我们已经了解了反射的基本概念以及它的原理,但是我们知道反射只能能用它来做些什么呢?

         其实在我们很多已经很熟的框架中都有它的身影,例如Hibernate框架中的关联映射,Spring框架:IOC(控制反转).反射可以实现各种框架功能,接下来我们通过一个实例来写一个很小很小的框架,通过此例子来理解反射真正的价值所在.

        接下来的例子主要功能是通过java反射来获取配置文件中的信息.通过配置文件,在程序运行的时候实例化所需要的类型的实例.

         首先先建立一个资源文件,这里我们用config.properties来进行配置相关信息.

          config.properties文件内容如下:指定类型为ArrayList类型.

[html] 
  1. ClassName=java.util.ArrayList  

          接下来建立一个反射测试类:

[java] 
  1. package com.tgb.java;  
  2.   
  3. import java.io.FileInputStream;  
  4. import java.io.IOException;  
  5. import java.io.InputStream;  
  6. import java.util.Collection;  
  7. import java.util.Properties;  
  8.   
  9. /** 
  10.  * 通过一个小例子来演示通过反射技术实现一个简单的框架. 
  11.  *  
  12.  * @author jnqqls 
  13.  * @group TGB 
  14.  * @version 1.0 
  15.  *  
  16.  * @comments 
  17.  */  
  18. public class ReflectTest {  
  19.   
  20.     /** 
  21.      * @param args 
  22.      * @throws IOException 
  23.      * @throws ClassNotFoundException 
  24.      * @throws IllegalAccessException 
  25.      * @throws InstantiationException 
  26.      */  
  27.     public static void main(String[] args) throws IOException,  
  28.             InstantiationException, IllegalAccessException,  
  29.             ClassNotFoundException {  
  30.   
  31.   
  32.         // 将文件读入数据流  
  33.         InputStream ipt = new FileInputStream("config.properties");  
  34.         // 创建Properties对象  
  35.         Properties ppt = new Properties();  
  36.         // 将数据流载入到ppt对象中.  
  37.         ppt.load(ipt);  
  38.         // 关闭占用资源.  
  39.         ipt.close();  
  40.   
  41.         // 获取配置文件中的名字.  
  42.         String className = ppt.getProperty("ClassName");  
  43.         // 通过反射创建className所对应的类的一个实例.  
  44.         @SuppressWarnings("unchecked")  
  45.         Collection<String> collections = (Collection<String>) Class.forName(  
  46.                 className).newInstance();  
  47.         collections.add(new String("a"));  
  48.         collections.add(new String("b"));  
  49.         System.out.println(collections.size());  
  50.   
  51.     }  
  52. }  

 

          通过测试,输出的数字为2.也就是集合中有两个对象.这里和我们通常的new是不一样的概念,我们的例子是在运行时所创建的对象,而我们常用的new是在编译的时候所生成的对象,因为可以配置我们想要的类型和生成的对象,这便为各种框架提高了支撑.

          现在对框架有了一个最简单的例子,通过对反射有了一定的了解便会更进一步的了解Spring框架,对于Spring框架的铺垫就是这些.接下来会继续介绍Spring框架的使用.

Class.forName( )静态方法的目的是为了动态加载类。在加载完成后,一般还要调用Class下的newInstance( )静态方法来实例化对象以便操作。因此,Class.forName( )是动态加载类是没有用的,其最终目的是为了实例化对象。调用 forName("X") 将导致命名为 X 的类被初始化。


01 package com.java.jvm;
02  
03 public class ClassTest {
04      public  static void main(String[] arg){
05          try {
06              Class  userClass = Class.forName("com.java.jvm.User");
07              System.out.println("userClass="+userClass);
08              User user = (User) userClass.newInstance();
09              System.out.println("user="+user);
10         catch (ClassNotFoundException e) {
11             e.printStackTrace();
12         catch (InstantiationException e) {
13             e.printStackTrace();
14         catch (IllegalAccessException e) {
15             e.printStackTrace();
16         }
17       }
18 }
打印结果:



1 userClass=class com.java.jvm.User
2 user=User [name=null, age=null, address=null]
 Class.forName("")返回的是类(Class)
 

 Class.forName("").newInstance()返回的是object 
其实和new 的关键字作用相同。


调用 forName("X") 将导致命名为 X 的类被初始化,这句话是官网API上的一句话,很迷茫,有点不理解,所以在User类中,添加了static语句块和User构造函数


01 package com.java.jvm;
02  
03 public class User {
04      
05     static{
06         System.out.println("static ---");
07     }
08      
09     public User(){
10         System.out.println("name="+name);
11         name="xiaotian";
12     }
13      
14     private String name;
15     private Integer age;
16     private String address;
17      
18     public String getName() {
19         return name;
20     }
21     public void setName(String name) {
22         this.name = name;
23     }
24     public Integer getAge() {
25         return age;
26     }
27     public void setAge(Integer age) {
28         this.age = age;
29     }
30     public String getAddress() {
31         return address;
32     }
33     public void setAddress(String address) {
34         this.address = address;
35     }
36     @Override
37     public String toString() {
38         return "User [name=" + name + ", age=" + age + ", address=" + address
39                 "]";
40     }
41      
42 }
结果打印:
1 static ---
2 userClass=class com.java.jvm.User
3 name=null
4 user=User [name=xiaotian, age=null, address=null]


forName("X") 执行的时候,调用了User中的静态语句块,newInstance()执行的时候调用了构造函数。

连接数据库的简单代码


01 // 驱动程序名
02            String driver = "com.mysql.jdbc.Driver";
03  
04            // URL指向要访问的数据库名student
05            String url = "jdbc:mysql://127.0.0.1:3306/student";
06  
07            // MySQL配置时的用户名
08            String user = "root";
09  
10            // MySQL配置时的密码
11            String password = "root";
12  
13            try {
14             // 加载驱动程序
15             Class.forName(driver);
16  
17             // 连续数据库
18             Connection conn = DriverManager.getConnection(url, user, password);
19  
20             if(!conn.isClosed())
21              System.out.println("Succeeded connecting to the Database!");
22  
23             // statement用来执行SQL语句
24             Statement statement = conn.createStatement();
25  
26             // 要执行的SQL语句
27             String sql = "select * from student";
28  
29             // 结果集
30             ResultSet rs = statement.executeQuery(sql);
其中加载数据库驱动
Class.forName(driver);加载mysql驱动,执行static语句块,使将Driver对象注册到DriverManager中,然后上面就获得了数据库连接


01 package com.mysql.jdbc  
02   
03 public class Driver extends NonRegisteringDriver implements java.sql.Driver {  
04 // ~ Static fields/initializers  
05 // --------------------------------------------- //   A
06 // Register ourselves with the DriverManager  
07 //  
08 static {  
09      t ry {   //使将Driver对象注册到DriverManager中
10                java.sql.DriverManager.registerDriver(new Driver());  
11            catch (SQLException E) {  
12               throw new RuntimeException("Can't register driver!");  
13            }  
14    }  
15 // ~ Constructors  
16 // -----------------------------------------------------------  
17 /**
18    * Construct a new driver and register it with DriverManager
19    *
20    * @throws SQLException
21    *              if a database error occurs.
22    */ 
23 public Driver() throws SQLException {  
24      // Required for Class.forName().newInstance()  
25 }  
26 }

          

转载地址:http://uuxkb.baihongyu.com/

你可能感兴趣的文章
博客文格式优化
查看>>
【托业】【新托业全真模拟】疑难语法题知识点总结(01~05)
查看>>
【SQL】group by 和order by 的区别。
查看>>
【Python】详解Python多线程Selenium跨浏览器测试
查看>>
Jmeter之参数化
查看>>
Shell 和Python的区别。
查看>>
Python 列表(list)、字典(dict)、字符串(string)常用基本操作小结
查看>>
Loadrunner之https协议录制回放报错如何解决?(九)
查看>>
python中xrange和range的异同
查看>>
列表、元组、集合、字典
查看>>
【Python】easygui小甲鱼
查看>>
【Python】关于Python多线程的一篇文章转载
查看>>
【Pyton】【小甲鱼】文件
查看>>
【Pyton】【小甲鱼】永久存储:腌制一缸美味的泡菜
查看>>
【Pyton】【小甲鱼】异常处理:你不可能总是对的
查看>>
APP性能测试工具
查看>>
【Pyton】【小甲鱼】类和对象
查看>>
压力测试工具JMeter入门教程
查看>>
作为一名软件测试工程师,需要具备哪些能力
查看>>
【Pyton】【小甲鱼】类和对象:一些相关的BIF(内置函数)
查看>>