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

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

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

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

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

  1. ClassName=java.util.ArrayList

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

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

通过测试,输出的数字为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 }

java反射(2)+Class.forName( )的更多相关文章

  1. 关于java反射里的.class、.getClass()、Class.Forname()

    博主在研究java反射这一章节时,曾被三个方法困扰多时,.class..getClass().Class.Forname(),先上代码 这是类A package cn.yonyong.net.tcp. ...

  2. 浅谈Java反射机制 之 获取类的字节码文件 Class.forName("全路径名") 、getClass()、class

    另一个篇:获取 类 的 方法 和 属性(包括构造函数) 先贴上Java反射机制的概念: AVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法: 对于任意一个对象,都能够调用它 ...

  3. java反射动态加载类Class.forName();

    1,所有的new出来的对象都是静态加载的,在程序编译的时候就会进行加载.而使用反射机制Class.forName是动态加载的,在运行时刻进行加载. 例子:直接上两个例子 public class Ca ...

  4. 第28章 java反射机制

    java反射机制 1.类加载机制 1.1.jvm和类 运行Java程序:java 带有main方法的类名 之后java会启动jvm,并加载字节码(字节码就是一个类在内存空间的状态) 当调用java命令 ...

  5. Java反射机制

    Java反射机制 一:什么事反射机制 简单地说,就是程序运行时能够通过反射的到类的所有信息,只需要获得类名,方法名,属性名. 二:为什么要用反射:     静态编译:在编译时确定类型,绑定对象,即通过 ...

  6. java反射(基础了解)

    package cn.itcast_01; /** *Person类 */ public class Person {    /** 姓名 */    private String name;     ...

  7. java基础知识(十一)java反射机制(上)

    java.lang.Class类详解 java Class类详解 一.class类 Class类是java语言定义的特定类的实现,在java中每个类都有一个相应的Class对象,以便java程序运行时 ...

  8. java基础知识(十一)java反射机制(下)

    1.什么是反射机制? java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象都能够调用他的属性和方法,这种动态获取属性和方法的功能称为java的反射机制. ...

  9. java反射学习之一反射机制概述

    一.反射机制背景概述 1.反射(reflection)是java被视为动态语言的一个关键性质 2.反射机制指的是程序在运行时能获取任何类的内部所有信息 二.反射机制实现功能概述 1.只要给定类的全名, ...

随机推荐

  1. Halloween Costumes(区间DP)

    Gappu has a very busy weekend ahead of him. Because, next weekend is Halloween, and he is planning t ...

  2. 腾讯云CVM使用记录--使用root权限

    1.su root 指令 ,执行下列命令获取root权限: sudo /bin/su - root 注意:严禁执行password命令,root密码默认不能被修改.

  3. 子串(codevs 4560)

    题目描述 Description 有两个仅包含小写英文字母的字符串A和B.现在要从字符串A中取出k个互不重叠的非空子串,然后把这k个子串按照其在字符串A中出现的顺序依次连接起来得到一个新的字符串,请问 ...

  4. [NOIP2003] 提高组 洛谷P1040 加分二叉树

    题目描述 设一个n个节点的二叉树tree的中序遍历为(1,2,3,…,n),其中数字1,2,3,…,n为节点编号.每个节点都有一个分数(均为正整数),记第i个节点的分数为di,tree及它的每个子树都 ...

  5. python学习之-- 面向对象

    面向对象(简写:OOP) 面向对象编程定义:利用类和对象来创建各种模型,来实现对真实世界的描述. 优点:使程序更容易理解和维护以及扩展代码. 类定义:用来描述具有相同的属性和方法的对象的集合.(简单讲 ...

  6. 【Java源码】集合类-队列Queue

    一.描述 队列Queue这种数据结构,通常指先进先出(FIFO)这种容器.可以模拟生活中依次排队这种场景. 下面是集合体系继承树: 二.Queue Queue和List一样都是Collection的子 ...

  7. MySQL命令行自动补全表名

    注意:在命令行下只有切换到数据库之后,才能补全表名,对于命令是不能补全的. 1.my.conf增加如下配置: [mysql] #no-auto-rehash auto-rehash #添加auto-r ...

  8. Web容器自己主动对HTTP请求中參数进行URLDecode处理

    这篇文章转载自 : Web容器自己主动对HTTP请求中參数进行URLDecode处理 如题.在Java中或许非常多人都没有注意到当我们发送一个http请求时,假设附带的參数被URLEncode之后,到 ...

  9. httpclient发送get请求

    /** * 获取httpclient的请求url地址 */ public static String getUrl(){ String url = "http://"+map.ge ...

  10. 【手记】小心在where中使用NEWID()的大坑 【手记】解决启动SQL Server Management Studio 17时报Cannot find one of more components...的问题 【C#】组件分享:FormDragger窗体拖拽器 【手记】注意BinaryWriter写string的小坑——会在string前加上长度前缀length-prefixed

    [手记]小心在where中使用NEWID()的大坑 这个表达式: ABS(CHECKSUM(NEWID())) % 3 --把GUID弄成正整数,然后取模 是随机返回0.1.2这三个数,不可能返回其它 ...