什么是反射?

  正常编译执行java文件时,会生成一个.class文件,反射就是一个反编译的过程,它可以通过.class文件得到一个java对象.一个类会有很多组成部分,比如成员变量,成员方法,构造方法等,反射可以通过加载类,解剖出类的各个组成部分.

为什么要用反射?

  我们需要访问一个类的方法或字段的时候,直接new一个该类的对象然后调用就好了,干嘛要用反射呢,刚学的时候我也不懂,并且学了也没机会用到,或者根本用不到,后来开始接触strut2,hibernate等一些框架的时候,才慢慢懂得了一点反射的强大之处,在框架中会有很多配置文件,而配置文件中一般只有一些类的全路径的字符串,而就是通过这些个字符串,就能得到这个类的对象,以及类中所有的信息.我给你这个类,当然你可以轻松得到它的实例,但如果我给你的只是这个类的路径的字符串呢?没有反射你就傻眼了吧.学习反射一般只会在写框架的时候用到,如果你没有到达写框架的高度,能够看懂别人的框架也是极好的.

这里面还涉及到一个静态编译和动态编译的概念,前者的意思就是在编译的时候已经绑定了对象,确定了对象,而动态编译就是知道运行的时候,才根据需要去绑定对象.

加载类:

  加载类就是获得类的字节码,要想通过反射获取到一个类的内部信息,首先得先获取到这个类的字节码对象.

  加载类有三种方式:

现在我有一个类User,我希望加载这个类,获得它的字节码对象:

package com.wang.reflect;

public class Demo01 {

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

        //第一种方式   通过Class的forName方法,注意使用目标类的全路径
Class clazz=Class.forName("com.wang.reflect.User"); //第二种方式 通过Object类的getClass()方法
Class clazz1=new User().getClass(); //第三种方式 通过类的.class属性
Class clazz2=User.class;
}
}

  一般第一种方式最常用,也最好用,因为看代码我们可以发现,后两种在编译前就必须要知道具体的类的,否则就无法通过编译,而第一种方式,没有那么大的强制性,他只是提供了一个空间,运行时你可以想把谁传给它就把谁传给它,这个类甚至可以不存在,后果只是抛出一个异常.

反射类的构造函数(Constructior):

  获得了Class对象以后就可以调用class的很多方法了,比如getConstructor(..),方法就可以获得构造器的对象.下面分别通过获取User类的无参和带参构造器,进而得到该类对象的例子,感受一下反射技术.

public class User {

    private String name;

    public User(){
System.out.println("无参构造函数");
} public User(String name){
this.name=name;
System.out.println("带一个参数的构造函数:::"+name);
}
}
//-----------------------------------------------------------------------------
@Test
public void test01() throws Exception{
//通过Class的forName方法,注意使用目标类的全路径
Class clazz=Class.forName("com.wang.reflect.User"); //通过无参构造器得到该类对象,
Constructor c=clazz.getConstructor(null);
User user=(User) c.newInstance(null); //通过带参构造器获得该类对象
Constructor c1=clazz.getConstructor(String.class);
User user1=(User)c1.newInstance("nick");
}

注意.在通过无参构造函数获得对象时,还可以直接调用User user=(User)clazz.newInstance();得到,内部的原理也是先调用了无参构造器,如上.注意,使用"newInstance"方法只能调用类的无参构造方法,这个操作实际相当于使用了new进行对象实例化.

反射类的方法(Method):

  一个类中总会有实现某些功能的方法,这些方法可能有返回值也可能没有返回值,可能有参数也可能没参数,可能是静态方法也可能是普通方法.下面通过例子分别讲解:

package com.wang.reflect;

public class User {

    private String name;

    public User(){
System.out.println("无参构造函数");
} public User(String name){
this.name=name;
System.out.println("带一个参数的构造函数:::"+name);
}
//1无参无返回值的方法login
public void login(){ System.out.println("用户登陆了");
}
//2带参有返回值的方法eat
public String eat(String name){
System.out.println("name"+"去吃饭去了");
return "eat";
}
//3带参无返回值的静态方法
public static void sleep(String name){
System.out.println(name +"去睡觉了");
}
}
//-----------------------------------------------------------------
@Test
public void test02() throws Exception{
User u=new User();
//通过Class的forName方法,注意使用目标类的全路径
Class clazz=Class.forName("com.wang.reflect.User"); //1获取无参无返回值的方法login
//获得一个方法名为"login"但是没有参数的Method对象
Method method=clazz.getMethod("login", null);
//第一个参数:要想执行这个login方法你总得告诉她是哪个User的login方法吧,第二个参数就是login方法的参数,这里为null
method.invoke(u, null);
//2获取有参有返回值的方法eat
Method method1=clazz.getMethod("eat", String.class);
String agrs=(String)method1.invoke(u, "超人");
//3获取带参无返回值的静态方法sleep,
     //静态方法 可以不提供User对象,传一个null即可
Method method2=clazz.getMethod("sleep", String.class);
method2.invoke(null, "蝙蝠侠");
} //执行之后打印结果为:

无参构造函数
用户登陆了
超人去吃饭去了
蝙蝠侠去睡觉了

反射类的字段:

@Test
public void test03() throws Exception{
User u=new User();
u.setName("钢铁侠");
//通过Class的forName方法,注意使用目标类的全路径
Class clazz=Class.forName("com.wang.reflect.User");
//注意需要用getDeclareField方法,getField只能获取到public的字段
Field f=clazz.getDeclaredField("name");
f.setAccessible(true);
String name=(String)f.get(u);
System.out.println(name);
}

 下面介绍一个使用反射的简单例子:

package com.wang.reflect;

import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ResourceBundle; interface Person {
public void location(String location);
} class Student implements Person{ @Override
public void location(String location) {
System.out.println("学生的工作地点是"+location);
} }
class Teacher implements Person{ @Override
public void location(String location) {
System.out.println("老师的工作地点是"+location);
} } class Factory{
public static Person getInstance(String str) throws Exception, IllegalAccessException, ClassNotFoundException{
Person person=(Person)Class.forName(str).newInstance();
return person;
}
} public class TestReflect { public static void main(String[] args) throws Exception {
//Person p=(Person)Class.forName("com.wang.reflect.Student").newInstance();
//p.location("学校");
Person p=Factory.getInstance("com.wang.reflect.Teacher");
p.location("学校"); }
}

这个例子使用了简单的工厂模式,调用person的location方法,通过反射,实际应用中并不会出现这样的代码,这里只是做一个反射的运用的演示.在测试代码中,只要简单的修改ForName方法中的字符串,就可以调用相应的方法.

Java基础--反射机制的知识点梳理的更多相关文章

  1. JAVA基础-反射机制

    什么是JAVA的反射机制 Java反射是Java被视为动态(或准动态)语言的一个关键性质.这个机制允许程序在运行时透过Reflection APIs取得任何一个已知名称的class的内部信息,包括其 ...

  2. java基础——反射机制

    反射机制是什么 反射机制就是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为jav ...

  3. java笔记--反射机制之基础总结与详解

    一.反射之实例化Class类的5种方式: java的数据类型可以分为两类,即引用类型和原始类型(即基本数据类型). 对于每种类型的对象,java虚拟机会实例化不可变的java.lang.Class对象 ...

  4. Java 类反射机制分析

    Java 类反射机制分析 一.反射的概念及在Java中的类反射 反射主要是指程序可以访问.检测和修改它本身状态或行为的一种能力.在计算机科学领域,反射是一类应用,它们能够自描述和自控制.这类应用通过某 ...

  5. java的反射机制

    一.java的反射机制浅谈 最近研究java研究得很给力,主要以看博文为学习方式.以下是我对java的反射机制所产生的一些感悟,希望各位童鞋看到失误之处不吝指出.受到各位指教之处,如若让小生好好感动, ...

  6. Java基础-类加载机制与自定义类Java类加载器(ClassLoader)

    Java基础-类加载机制与自定义类Java类加载器(ClassLoader) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 关于类加载器的概念和分类我就不再废话了,因为我在之前的笔 ...

  7. Java基础-反射(reflect)技术详解

    Java基础-反射(reflect)技术详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.类加载器 1>.JVM 类加载机制  如下图所示,JVM类加载机制分为五个部分 ...

  8. java的反射机制浅谈(转)

    原文链接:java的反射机制浅谈 一.java的反射机制浅谈 1.何谓反射机制 根据网文,java中的反射机制可以如此定义: JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性 ...

  9. 深入浅出学习hibernate框架(三):java的反射机制

    上篇博客写到了JDBC的基本操作,今天准备写一篇关于JAVA反射机制的文章,因为java的反射机制和上一篇JDBC都是Hibernate框架的基本要素.在Hibernate的运行机制中,这两块的内容正 ...

随机推荐

  1. linux配置ftp高级权限

    建一个用于管理的ftp高级账号,ftproot,定义它的目录,也就是我们存放项目的地址,所属组www, useradd -d /home/www -g www ftproot www里存放很多项目,我 ...

  2. Centos 编写 service 启动

    Centos 系统服务脚本目录: [html] view plaincopyprint?   /usr/lib/systemd/ 有系统(system)和用户(user)之分, 如需要开机没有登陆情况 ...

  3. jQuery模仿淘宝商品评价

    最近做项目要做个商品评价的功能,我直接就跑到淘宝那里去研究了,可看着晕晕的,还不知道他是怎么做的,于是把图抠了下来,自己写了一个,接下来就展示一下我是怎么做的,大家有不同的实现方法可要记得分享一下呀. ...

  4. 资深人士剖析微软开源.NET事件:战略重心已经从PC转移到云端

    本文是雷锋网对我的访谈整理的文章,源地址是 http://www.leiphone.com/news/201411/6KaGhD7PDABnvrRf.html 2014年11月13日,微软表示开源.N ...

  5. ENode框架Conference案例分析系列之 - 复杂情况的读库更新设计

    问题背景 Conference案例,是一个关于在线创建会议(类似QCon这种全球开发者大会).在线管理会议位置信息.在线预订某个会议的位置的,这样一个系统.具体可以看微软的这个项目的主页:http:/ ...

  6. 自己动手模拟开发一个简单的Web服务器

    开篇:每当我们将开发好的ASP.NET网站部署到IIS服务器中,在浏览器正常浏览页面时,可曾想过Web服务器是怎么工作的,其原理是什么?“纸上得来终觉浅,绝知此事要躬行”,于是我们自己模拟一个简单的W ...

  7. .Net开发笔记(十七) 应用程序扩展

    在很多场合,我们需要在已有软件程序上增加一些新的功能,几乎所有原因是因为原有软件功能不能满足我们的需要,我们平时做的插件就属于这种情况,最常见的是VS IDE的插件开发,网上老外写的一篇关于插件开发的 ...

  8. 企业IT管理员IE11升级指南【5】—— 不跟踪(DNT)例外

    企业IT管理员IE11升级指南 系列: [1]—— Internet Explorer 11增强保护模式 (EPM) 介绍 [2]—— Internet Explorer 11 对Adobe Flas ...

  9. MVC缓存

    MVC入门系列教程-视频版本,已入驻51CTO学院,文本+视频学效果更好哦.视频链接地址如下: 点我查看视频.另外,针对该系列教程博主提供有偿技术支持,群号:226090960,群内会针对该教程的问题 ...

  10. HTTPS那些事(二)SSL证书(转载)

    原创地址:http://www.guokr.com/post/116169/   从第一部分HTTP工作原理中,我们可以了解到HTTPS核心的一个部分是数据传输之前的握手,握手过程中确定了数据加密的密 ...