反射:reflection

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()

Class cla=People.class;

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

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

//方法三

try {

Class claa=(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的方法,包括继承的,接口中声明的和自己定义的

获得所有的公开方法:

Class clazStudent = Student.class;

Method[] publicMethods = clazStudent.getMethods();

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

for (Method method : publicMethods) {

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

}

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

Class c = Student.class;

Method[] declaredMethods = c.getDeclaredMethods();

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

for (Method m : declaredMethods) {

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

}

Field[] getDeclaredFields()

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

Field[] getFields()

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

获得所以的公开属性:

Class c = Student.class;

Field[] publicMethods = c.getFields();

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

for (Field field : publicMethods) {

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

}

获得本类中定义的属性:

Class clazStudent = 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 作用,全方位解读Java反射(reflection)相关推荐

  1. java 内部类 作用,内部类,java内部类的四大作用

    内部类,java内部类的四大作用 在java中,允许一个类的定义位于另一个类的内部,前者称为内部类,后者称为外部类. inner class 一般用在定义它的类或语句块之内,在外部引用它时必须给出完整 ...

  2. java多态 作用_关于Java三大特性之多态的总结

    面向对象的三大特性:封装.继承.多态.从一定角度来看,封装和继承几乎都是为多态而准备的.这是我们最后一个概念,也是最重要的知识点. 1.定义: 多态:指允许不同类的对象对同一消息做出响应.即同一消息可 ...

  3. java快排算法解读,java 快排的思路与算法

    java 快排的思路与算法 有时候面试的时候的会问道Arrays.sort()是怎么实现的,我以前根本不知道是什么东西,最近点进去看了一下.直接吓傻, //看到这个时候还是比较淡定的,可怕的事情来了. ...

  4. java中解析xml解读,java解析xml(JDOM)

    下面通过一个简单的例子说明一下怎么用JDOM这一适合Java程序员习惯的工具包来解析XML文档. 为了简单,我用了如下XML作为要解析的XML文件: rjzjh 60.0 够简单的吧,但它对于我们关心 ...

  5. java衍生作用_关于JAVA衍生出的一点想法

    你们好,好久没有更新博客了,今天更新的博客中,不讨论技术,主要讨论的是一些我的想法,博主在前些天和一位作PHP的同事有过一次短暂的碰撞,在这个过程当中,对JAVA有了更深刻一些的思考,在这里分享出来供 ...

  6. 线程?对!!这就是Java线程超级细致解读---Java学习总结

    线程 要想先了解线程,我们先看看什么是进程 进程是指可执行程序并存放在计算机存储器的一个指令序列,它是一个动态执行的过程 比如说,我们在平时使用电脑的时候,都会挂着微信,QQ,有时候还要打开音乐播放器 ...

  7. java 反射Reflection;Class类

    1.反射机制概述 java能够反射的前提:已经加载过这个类 反射可以通过类名来寻找这个类的所有相关信息.类似于人类的记忆,事先在记忆中有了这个事物的信息,人就可以通过名字来在记忆中寻找事物的具体信息. ...

  8. java 序列化概念和作用_结合代码详细解读Java序列化与反序列化概念理解

    Java序列化与反序列化是什么?为什么需要序列化与反序列化?如何实现Java序列化与反序列化?本文围绕这些问题进行了探讨. 1.Java序列化与反序列化 Java序列化是指把Java对象转换为字节序列 ...

  9. C#反射(Reflection)详解

    1. 什么是反射 2. 命名空间与装配件的关系 3. 运行期得到类型信息有什么用 4. 如何使用反射获取类型 5. 如何根据类型来动态创建对象 6. 如何获取方法以及动态调用方法 7. 动态创建委托 ...

最新文章

  1. 代码整理工具_程序员软件:程序员有哪些常用又好用的编码小工具?
  2. Flask-RESTful的简单使用
  3. 解决报错OMP: Error #15: Initializing libiomp5md.dll, but found libiomp5md.dll already initialized.
  4. C++ Primer 5th笔记(chap 18 大型程序工具) 重载与命名空间
  5. bzoj3895: 取石子(博弈论,记忆化搜索)
  6. 2019 ASP.NET Core 之微调查报告,新鲜出炉
  7. easypoi 导入oracle,记一次由openjdk导致的poi错误(easyexcel)
  8. 只能发邮件不能接受_《GTA5》R星发邮件问候玩家会发生什么?以下操作一个也别碰...
  9. bug3-自定义层的注意事项
  10. 数据库开发工程中,一些不常遇到的难题
  11. 美通企业日报 | 英特尔百度签署新合作备忘录;佛山照明与阿里云战略合作物联网生态...
  12. 计算机未安装flash,win10系统提示未安装Flash的解决方法
  13. python怎么换背景颜色_Python给照片换底色(蓝底换红底)
  14. 千机智能孙海锋:期待与国际同行在高端制造领域同台竞技(自主可控CAM软件:UltraCAM)
  15. 怎样获取网页视频下载链接
  16. Nginx正则表达式locationrewrite
  17. HDUOJ 1069 Monkey and Banana
  18. mysql interval weekday_Mysql DATE_SUB(NOW(), INTERVAL 1 DAY) 24 hours or weekday?
  19. Debian 制作U盘安装盘启动器
  20. 在jupyter安装jieba出错ModuleNotFoundError: No module named ‘jieba‘的解决办法

热门文章

  1. 【数据结构】栈的实现(C语言)
  2. WASC Threat Classification 安全威胁分类
  3. android 计算图片大小
  4. 考试管理系统-刷题系统案题目选项编写
  5. 最长上升子序列(LIS) 学习总结
  6. 对互联网VC的10点看法
  7. php 提取图片的特征,让机器“看见”:图像数据的特征提取方法
  8. 黑群辉DSM 6.2.3 系统安装
  9. ARMv7 Processor modes
  10. ASP.NET 页面中的 ValidateRequest属性