JAVA提供了一种反射机制,反射也称为反省。

  java程序运行以后内存中就是一堆对象,除了对象什么都没有。

  找对象

  拉关系

  瞎折腾

  对象在运行过程中能否有一种机制查看自身的状态,属性和行为。这就是反射机制。

  每一个运行中的类,都会有一个class对象,表示这个类的类对象。

  获取class对象的方法:

  1.引用名.getClass()

  2.类名.getClass()

  3.Class.forName()

  //方法一 引用.getClass()

  People p=new People();

  System.out.println(p.getClass().getName()); //包括包名

  System.out.println(p.getClass().getSimpleName());//不包括包名

  //方法二 类名.getClass()

  Classcla=People.class;

  System.out.println(cla.getName());

  System.out.println(cla.getSimpleName());

  //方法三

  try {

  Classclaa=(Class)Class.forName(com.java.reflection.People);

  System.out.println(claa.getName());

  System.out.println(claa.getSimpleName());

  } catch (ClassNotFoundException e) {

  // TODO Auto-generated catch block

  e.printStackTrace();

  }

  Java已经为我们提供了这样一个类:java.lang.Class,我们无需自己定义Class类,通过Class对象我们可以得到:

  类继承自哪个类

  实现了哪些接口

  有哪些属性

  有哪些方法

  有哪些构造方法

  getName(): 获得类的名称,包括包名

  getSimpleName(): 获得类的名称,不包括包名

  getSuperClass(): 获得本类的父类的class对象

  getInterfaces():获得本类所实现的所有接口的class对象

  class对象的作用:

  public Method[] getDeclaredMethods() throws SecurityException

  取得所有当前类声明的方法,包括public,protected,默认,private四种访问权限的方法,但是不包括继承的方法

  public Method[] getMethods() throws SecurityException

  取得所有public的方法,包括继承的,接口中声明的和自己定义的

  获得所有的公开方法:

  ClassclazStudent = Student.class;

  Method[] publicMethods = clazStudent.getMethods();

  System.out.println(===========所有public方法===========);

  for (Method method : publicMethods) {

  System.out.println(method.getName());

  }

  获得所以的本类中定义的方法:

  Classc = Student.class;

  Method[] declaredMethods = c.getDeclaredMethods();

  System.out.println(===========所有当前的类自己定义的方法===========);

  for (Method m : declaredMethods) {

  System.out.println(m.getName());

  }

  Field[] getDeclaredFields()

  取得所有当前类自己定义的属性,包括四种访问权限的

  Field[] getFields()

  取得所有public的属性,包括继承的,接口中声明的和自己定义的

  获得所以的公开属性:

  Classc = Student.class;

  Field[] publicMethods = c.getFields();

  System.out.println(============所有public属性============);

  for (Field field : publicMethods) {

  System.out.println(field.getName());

  }

  获得本类中定义的属性:

  ClassclazStudent = Student.class;

  Field[] declaredFields = clazStudent.getDeclaredFields();

  System.out.println(==========获取当前类自己定义的属性==========);

  for (Field field : declaredFields) {

  System.out.println(field.getName());

  }

  java.lang.reflect.Field类

  通过Class对象的如下方法可以获得Field对象

  Field getDeclaredField(String name)

  Field getField(String name)

  Field[] getDeclaredFields()

  Field[] getFields()

  每个Java程序执行前都必须经过编译、加载、连接、和初始化这几个阶段

  加载:查找并加载类的二进制数据

  连接:1.验证:确保被加载的类的正确性

  2.准备:为类的静态变量分配内存,并将其初始化为默认值

  3.解析:把类中的符号引用转换为直接引用

  初始化:为类的静态变量赋予正确的初始值

  i、加载是指将编译后的java类文件(也就是.class文件)中的二进制数据读入内存,并将其放在

  运行时数据区的方法区内,然后再堆区创建一个Java.lang.Class对象,用来封装类在方法区的数据结构。

  即加载后最终得到的是Class对象,并且更加值得注意的是:该Java.lang.Class对象是单实例的,

  无论这个类创建了多少个对象,他的Class对象是唯一的!!!!。

  而 加载并获取该Class对象可以通过三种途径:

  Class.forName(类的全路径)、实例对象.class(属性)、实例对象getClass()。

  在连接和初始化阶段,其实静态变量经过了两次赋值:

  第一次是静态变量类型的默认值;

  第二次是我们真正赋给静态变量的值。

  Java对类的使用分为两种方式:主动使用和被动使用

  主动使用:

  1.创建类的实例

  2.访问某个类或接口的静态变量,或者对该静态变量赋值

  3.调用类的静态方法

  4.反射:Class.forName(com.java.reflection.Person),即:Class.forName(包名.类名)

  5.初始化一个类的子类

  6.Java虚拟机启东市被标明为启动类的类

  而类的初始化时机正是java程序对类的首次主动使用,除了以上6中方式,

  其他对类的使用都是被动使用,都不会导致类的初始化。 并且应该注意以下几个方面:

  调用ClassLoader类的loadClass方法加载一个类,并不是对类的主动使用,不会导致类的初始化

  当Java虚拟机初始化一个类时,要求它的所有父类都已经被初始化,但是这条规则并不适用于接口。

  在初始化一个类时,并不会先初始化它所实现的接口。

  在初始化一个接口时,并不会先初始化它的父接口。

  因此,一个父接口并不会因为它的子接口或者实现类的初始化而初始化。只有当程序首次使用特定接口的

  静态变量时,才会导致该接口的初始化。

  接口的两重性:可以把接口当做类(因为在接口中有静态变量时,他可以被初始化);

  接口就是接口,和类无关(接口中 没有构造方法,所以不能被初始化)

  从JVM的角度看,我们使用关键字new创建一个类的时候,这个类可以没有被加载。但是

  使用Class对象的newInstance()方法的时候,就必须保证:1、这个类已经加载;

  2、这个类已经连接了。而完成上面两个步骤的正是Class的静态方法forName()所完成的,

  这个静态方法调用了启动类加载器,即加载 java API的那个加载器。

  现在可以看出,Class对象的newInstance()(这种用法和Java中的工厂模式有着异曲同工之妙)

  实际上是把new这个方式分解为两步,即首先调用Class加载方法加载某个类,然后实例化。

  这样分步的好处是显而易见的。我们可以在调用class的静态加载方法forName时获得更好的灵活性,

  提供给了一种降耦的手段。

  最后用最简单的描述来区分new关键字和newInstance()方法的区别:

  newInstance: 弱类型。低效率。只能调用无参构造。

  new: 强类型。相对高效。能调用任何public构造。

  使用反射的好处:

  1.创建的对象不用new

  2.可以动态创建对象(把要创建的对象的类型写在配置文件中,每次程序启动读取配置文件,再自动创建对象)

全方位解读Java反射(reflection)的更多相关文章

  1. 公共技术点( Java 反射 Reflection)

    转载路径:http://p.codekk.com/blogs/detail/5596953ed6459ae7934997c5 本文为 Android 开源项目源码解析 公共技术点中的 Java 反射 ...

  2. 公共技术点之 Java 反射 Reflection

    本文摘录地址: http://codekk.com/open-source-project-analysis/detail/Android/Mr.Simple/%E5%85%AC%E5%85%B1%E ...

  3. Java反射reflection与注解annotation的应用(自动测试机)

    一.关于自动测试机 1.什么是自动测试机? 对类中的指定方法进行批量测试的工具 2.自动测试机有什么用? a.避免了冗长的测试代码 当类中的成员方法很多时,对应的测试代码可能会很长,使用测试能够让测试 ...

  4. Java反射机制(Reflection)

    Java反射机制(Reflection) 一.反射机制是什么 Java反射机制是程序在运行过程中,对于任意一个类都能够知道这个类的所有属性和方法;对于任意一个对象都能够调用它的任意一个方法和属性,这种 ...

  5. Java - 反射机制(Reflection)

    Java - 反射机制(Reflection)     > Reflection 是被视为 动态语言的关键,反射机制允许程序在执行期借助于 Reflection API 取得任何类的       ...

  6. Java反射(Reflection)

    基本概念 在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法? 答案是肯定的. 这种动态获取类的信息以及动态调用对象的方法的功能来自于J ...

  7. java 反射(Reflection)

    看了很多关于java 反射的文章,自己把所看到的总结一下.对自己,对他人或多或少有帮助吧. Java Reflection是什么? 首先来看看官方文档Oracle里面对Reflection的描述: R ...

  8. java学习--Reflection反射机制

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

  9. Java反射机制Reflection

    Java反射机制 1 .class文件 2 Class类 3 Class类与反射机制 4 Java反射机制的类库支持及简介 5 反射机制的定义与应用 6 反射机制Demo Java反射机制demo(一 ...

随机推荐

  1. Powershell计算时间间隔(New-TimeSpan)

    在Windows PowerShell里New-TimeSpan cmdlet提供了一种方法做日期算法. 计算时间间隔: 这个命令告诉你今天的日期与2006年除夕之间的天数: New-TimeSpan ...

  2. Oracle Database Documentation

    Oracle数据库的发展简史 ORDBMS对象-关系数据库管理系统 Oracle Schema Objects Oracle Schema Objects——Tables——Overview of T ...

  3. FW: AMD, CMD, CommonJS和UMD

    javascript 我是豆腐不是渣 4月5日发布 推荐 2 推荐 收藏 32 收藏,486 浏览 今天由于项目中引入的echarts的文件太大,requirejs经常加载超时,不得不分开来加载ech ...

  4. shader常用

    1 模型空间转裁剪空间 UnityObjectToClipPos(v.vertex) 2 模型空间转世界空间 mul( unity_ObjectToWorld, v.vertex ) 3 雾三件套 U ...

  5. Vue中通过鼠标移入移出来添加或取消class样式(active)

     基础知识: 先写一下vue中鼠标移入移出的基础知识,移入的触发事件是 @mouseenter,移出的触发事件是@mouseleave,知道这两个方法就简单了 基础知识的例子 <div clas ...

  6. vc判断当前用户是否具有administrator 权限代码

    BOOL IsAdmin() { HANDLE hAccessToken; BYTE * InfoBuffer = ]; PTOKEN_GROUPS ptgGroups; DWORD dwInfoBu ...

  7. Redis配置文件的使用

    Redis基本配置 常规配置 进到配置文件下 vi /etc/redis.conf 写入配置项 port 1111 # 配置端口号 daemonize yes # 是否后台运行 daemonize y ...

  8. redis中默认有多少个哈希槽?

    Redis 集群中内置了 16384 个哈希槽,当需要在 Redis 集群中放置一个 key-value时,redis 先对 key 使用 crc16 算法算出一个结果,然后把结果对 16384 求余 ...

  9. Oracle11g的安装卸载及经常使用工具的使用

    Oracle11g的安装卸载及经常使用工具的使用 目的: (1) 掌握Oracle 11g数据库的安装与卸载过程. Oracle11g的安装卸载及经常使用工具的使用 目的: (1) 掌握Oracle  ...

  10. select * 为什么不好? limit 1 为什么好? --mysql SQL语句优化

    问题一: Select * from  student;  这种语句不好 我的理解:根据Innode存储引擎以及网上的各种资料所说的innodb的B+树索引结构可以分析出,当在非聚集索引列上搜索若用s ...