1.基础概念

  class类:

  1.1java是面向对象的,但是在java中存在两种东西不是面向对象的

    一种是普通的数据类型,这也是封装数据类存在的原因.

    二种是静态静态成员.

  1.2所以我们首先要理解,类也是一种对象,类是java.lang.Class类的对象.

  1.3反射的操作其实是执行了编译,获得了类的编译信息,也就是字节码.

  1.4获取类类型可以有三种方式:

DemoGetClassType.java
/**
* Created by garfield on 2016/10/11.
* 三种方式获得类类型
*/
public class DemoGetClassType {
public static void main(String[] args) {
//car是一个对象
Car car = new Car();
//那么既然Car类型为一个对象,那么如何表示Car这个类:
//查看Class源码发现类是有构造方法的,但是是私有的,只有java虚拟机才能创建Class实例,所以我们要通过其他方法来表示类对象
//类是Class的实例对象,称之为该类的类类型(class type) //可以有三种写法
//第一种:每一个类都有一个静态成员:class
Class c1 = Car.class; //第二种:利用getClass()方法
Class c2 = car.getClass(); //类类型是相等的
System.out.println(c1 == c2);
Class c3 = null;
try {
c3 = Class.forName("com.learn.reflect.a_GetClassType.Car");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
System.out.println(c2 == c3); //通过类类型可以创建类实例,其实际是通过调用类的无参构造方法,
try {
Car car1 = (Car)c1.newInstance();
car1.run();
} catch (InstantiationException e) {
//如果丢失无参构造方法,抛出InstantiationException,也就是实例化异常
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} }
}
class Car { void run(){
System.out.println("i can run");
}
}

2.动态加载类

  2.1在类对象的forName()方法中,是可以表示动态加载类的,此处区分:

    一,在编译时刻加载的类是静态加载类

    二,运行时刻加载类是动态加载类

  2.2利用动态时刻加载可以避免一个功能出错的时候整个系统都不能运行

DemoStaticLoad.java
/**
* Created by garfield on 2016/10/13.
*/
public class DemoStaticLoad { public static void main(String[] args) {
//new创建对象 是静态加载类,在编译时刻就需要加载任何可能使用到的类
//这个类当中,由于都是new加载,所以当bus或者jeep有任何一个类不存在时,编译报错
//此时应当考虑使用动态加载,尤其是当类数量多的时候
if("bus".equals(args[0])){
Bus bus = new Bus();
bus.start();
}
if("jeep".equals(args[0])){
Jeep jeep = new Jeep();
jeep.start();
}
}
}

DemoDynasticLoad.java

/**
* Created by garfield on 2016/10/13.
*/
public class DemoDynasticLoad { public static void main(String[] args) {
try {
//动态加载类,在运行时刻编译,只有当运行类不存在时才会报错
//但凡这种多功能编程,都应该设计成这种不用非重新编译不可的结构
Class Wheel = Class.forName(args[0]);
Wheel wheel = (Wheel) Wheel.newInstance();
wheel.start();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}

3.获取类的信息

  3.1普通的数据类型以及void同样存在类类型

  3.2可以获取类的方法,成员变量,构造函数,包名,父类,接口等信息

DemoGetClassInformation.java
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method; /**
* Created by garfield on 2016/10/13.
* 打印出关于输入类型的方法和参数,成员变量,构造函数
*/
public class DemoGetClassInformation {
public static void main(String[] args) {
printClassInformation("aa");
printClassInformation(11);
} static void printClassInformation(Object obj) {
Class objClass = obj.getClass();
System.out.println(objClass.getName());
//获取不带前缀的类名
System.out.println(objClass.getSimpleName());
/**
* 看源码可以看出,getMethods返回了所有的public方法,其中包括继承而来的方法
* 如果想获取本身的所有方法,用getDeclaredMethods()
*/
Method[] methods = objClass.getMethods(); for (Method method : methods) {
System.out.println("================================");
System.out.println("方法名称是" + method.getName());
System.out.println("返回值是:" + method.getReturnType().getName());
//获取参数列表,返回值是参数的类类型
Class[] params = method.getParameterTypes();
for (Class param : params) {
System.out.println("参数:" + param.getName());
}
}
/**
* java.lang.reflect.Field封装了成员变量
* 与方法相仿,getFields()获得的是public变量,如果要获取本身声明的私有变量,采用getDeclaredFields()
*/
System.out.println("=======打印成员变量=======");
Field[] fields = objClass.getDeclaredFields();
for (Field field : fields) {
System.out.println("成员变量类型:" + field.getType().getName() + ", 成员变量名" + field.getName());
} /**
* java.lang.Constructor封装构造函数
* 与上述相仿,getConstructors()得到public构造函数,getDeclaredConstructors()获得声明构造函数
*/
System.out.println("=======打印构造函数=======");
Constructor[] constructors = objClass.getDeclaredConstructors();
for (Constructor constructor : constructors) {
System.out.println("构造函数名" + constructor.getName());
Class[] conParas = constructor.getParameterTypes();
for (Class conPara : conParas) {
System.out.println("参数:" + conPara.getName());
} }
}
}

4.方法的反射

  4.1需要理解方法反射的操作 method.invoke(对象,参数列表)

  4.2调用方法是传入的是实例和参数

DemoMethodReflection.java
/**
* Created by garfield on 2016/10/13.
* 方法反射实例
*/
public class DemoMethodReflection {
public static void main(String[] args) {
//先得到类信息
MathCount mathCount = new MathCount();
Class mathCountClass = mathCount.getClass();
try {
/**
* 获得方法,然后进行方法反射,如果有返回值可以获得返回值
* 注意可变参数两种写法
* 1.new class[]{int.class,int.class}
* 2.int.class,int.class
*/
Method method = mathCountClass.getMethod("add",new Class[]{int.class,int.class});
method.invoke(mathCount,new Object[]{22,44});
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} } }
class MathCount { public void add(int a, int b){
System.out.println(a + b);
}
}

5.集合的本质有助于我们理解方法反射和正常调用的不同(反射时绕过了编译)

  5.1集合中通过反射可以放入不同类型的元素

  5.2不同泛型的集合,其本质是同一个类类型

DemoSetNature.java

/**
* Created by garfield on 2016/10/13.
*/
public class DemoSetNature {
public static void main(String[] args) {
ArrayList arrayList = new ArrayList();
ArrayList<String> arrayList1 = new ArrayList<String>();
Class arrayListClass = arrayList.getClass();
Class arrayList1Class = arrayList1.getClass();
System.out.println(arrayList1Class == arrayListClass);
/**
* 结果为true说明,编译之后集合的泛型是去泛型化的
* 泛型只在编译阶段有效
*/
try {
Method method = arrayListClass.getMethod("add",Object.class);
//!绕过编译之后可以添加其他类型的数据
method.invoke(arrayList1,200);
System.out.println(arrayList1);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}

由浅到深理解java反射的更多相关文章

  1. 深入理解Java反射+动态代理

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

  2. 理解Java反射机制

    理解Java反射机制 转载请注明出处,谢谢! 一.Java反射简介 什么是反射? Java的反射机制是Java特性之一,反射机制是构建框架技术的基础所在.灵活掌握Java反射机制,对学习框架技术有很大 ...

  3. 由浅入深理解----java反射技术

    java反射机制详解 java反射机制是在运行状态下,对任意一个类可以获取该类的属性和方法,对任意一个对象可以调用其属性和方法.这种动态的获取信息和调用对象的方法的功能称为java的反射机制 clas ...

  4. 理解Java反射

    一.反射简介 Java让我们在运行时识别对象和类的信息,主要有2种方式:一种是传统的RTTI,它假定我们在编译时已经知道了所有的类型信息:另一种是反射机制,它允许我们在运行时发现和使用类的信息. 1. ...

  5. 深入理解Java反射

    要想理解反射的原理,首先要了解什么是类型信息.Java让我们在运行时识别对象和类的信息,主要有2种方式:一种是传统的RTTI,它假定我们在编译时已经知道了所有的类型信息:另一种是反射机制,它允许我们在 ...

  6. Java复习总结——详细理解Java反射机制

    反射是什么 反射的作用用一句简单的话来讲就是可以对代码进行操作的代码,这个特性经常在被用于创建JavaBean中,通常造轮子的人会用到这个特性,而应用程序员用到这个特性的场景则较少. 能够分析类能力的 ...

  7. 如何理解java反射?

    一.反射基本概念 反射之中包含了一个"反"的概念,所以要想解释反射就必须先从"正"开始解释,一般而言,当用户使用一个类的时候,应该先知道这个类,而后通过这个类产 ...

  8. 由浅到深理解ROS(1)

    ROS机器人操作系统 ( Robot Operating System 或简称 ROS),可以帮助提高机器人软件的开发效率.ROS能够提供类似传统操作系统的诸多功能,如硬件抽象.底层设备控制.常用功能 ...

  9. JavaScript基础知识从浅入深理解(一)

    JavaScript的简介 javascript是一门动态弱类型的解释型编程语言,增强页面动态效果,实现页面与用户之间的实时动态的交互. javascript是由三部分组成:ECMAScript.DO ...

随机推荐

  1. servlet 用法

    引入servlet的jar包,这个包在tomcat的lib下 新建一个servlet文件继承httpServlet,要实现里面的doGet或者doPost方法 在web.xml文件中配置 在form表 ...

  2. c#.net 获取时间日期年月日时分秒格式

    今天写代码发现两个比较不错的分享下:1.DateTime.ParseExact很多时候我们获取的时间是数字形式表示的,好比20140127134015.927856,通过这个方法DateTime.Pa ...

  3. 4、Spring+MyBatis增删改查

    0.oracle数据库脚本 create table userinfo (id ), name ), password telephone ), isadmin )); --4.2 用户表序列 cre ...

  4. UltraEdit 中的常用正则表达式

    正则表达式 (UltraEdit Syntax):   % 匹配行首 - 表明要搜索的字符串一定在行首.   $ 匹配行尾 - 表明要搜索的字符串一定在行尾   ? 匹配除换行符外的任一单个字符.   ...

  5. Openjudge-计算概论(A)-奇数求和

    描述: 计算非负整数 m 到 n(包括m 和 n )之间的所有奇数的和,其中,m 不大于 n,且n 不大于300.例如 m=3, n=12, 其和则为:3+5+7+9+11=35. 输入两个数 m 和 ...

  6. 关于No architectures to compile for (ONLY_ACTIVE_ARCH=YES, active arch=x86_64, VALID_ARCHS=armv7 armv7s)使用百度地图的解决办法

    出现的原因:armv7s是应用在iPhone 5 A6 的架构上的解决的方式:1,在Project target里“Architectures”设置为“Standard (armv7,armv7s)” ...

  7. ecos 问题答疑(转)

    1.为什么我购买的是源码版,但是我的base/ego.php(或者base/ego/目录下文件)却是加密的?  答:ego 源码商业授权文件仅用于和商派软件签订源码协议的商业用户按照甲乙的源码保护约定 ...

  8. Ubuntu iptalbes 保存配置

     ubuntu 保存防火墙命令,iptables方式:1.iptables 配置好策略2.iptables-save > /etc/network/iptables.up.rules ,配置的策 ...

  9. MediaWiki搭建教程

    ♦  MediaWiki是什么以及有什么作用,这里我就不再阐述了,网上可以查到很多.这里只是简单记录一下搭建wiki的基本过程,给一些热爱捯饬的小伙伴一些参考. ♦  其实wiki的搭建本身很简单,最 ...

  10. How can I create an Asynchronous function in Javascript?

    哈哈:)我的codepen 的代码笔记是:http://codepen.io/shinewaker/pen/eBwPxJ --------------------------------------- ...