一、反射

1、反射概念

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

  要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象。

2、Java 反射机制的主要用途

1、在运行时判断任意一个对象所属的类。

2、在运行时构造任意一个类的对象。

3、在运行时判断任意一个类所具有的成员变量和方法。

4、在运行时调用任意一个对象的方法。

3、三种获取Class实例对象的方式

1、Person p = new Person();

  Class c = p.getClass();

  已知类的对象,通过 getClass() 方法获取 Class 实例对象。

2、Class c2 = Person.class;

  任意数据类型都具备一个 class 静态成员变量,看上去要比第一种方式简单。

3、将类名作为字符串传递给Class类中的静态方法 forName 即可。

  Class c3 = Class.forName("Person");

 import com.reflect.pojo.Product;
import org.junit.Test; /**
* @author zt1994 2018/3/5 14:25
*/
public class TestReflect { /**
* 测试三种获取Class对象的方法
* @throws Exception
*/
@Test
public void testGetClass() throws Exception {
//实例化类的三种方法 任何对象都是Class的实例
//第一种 对象名.getClass()
Product product = new Product();
Class<? extends Product> aClass1 = product.getClass();
System.out.println(aClass1); //class com.reflect.pojo.Product
//第二种 类型.class
Class<Product> aClass2 = Product.class;
System.out.println(aClass2);
//第三种 Class 类中的静态方法 static Class<?>  forName(String className) className是类或者接口的权限定名
Class<?> aClass3 = Class.forName("com.reflect.pojo.Product");
System.out.println(aClass3);
//比较
System.out.println(aClass1==aClass2); //true
System.out.println(aClass1==aClass3); //true
System.out.println(aClass2==aClass3); //true
}
}

4、反射的作用

1、增加程序的灵活性,避免将程序写死到代码里(解除硬编码的问题);

2、Java的反射机制它知道类的基本结构,可以动态的去获取类这样的结构的结构;

3、可以让程序员在不知道其它程序员会有什么类的时候就编写完成自己的代码;

4、反射的优点:灵活,功能强大(可以拿到私有的....);

5、反射的缺点:破坏封装,影响性能;

5、反射运用(常用 API)

1、获取构造方法

getConstructors  不能获取私有的构造方法。

getDeclaredConstructors  可以获取所有构造方法,包括私有的。

  Product类:

 public class Product {
private Integer id;
private String productName;
private Integer classifyId;
private String brand; public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getProductName() {
return productName;
} public void setProductName(String productName) {
this.productName = productName;
} public Integer getClassifyId() {
return classifyId;
} public void setClassifyId(Integer classifyId) {
this.classifyId = classifyId;
} public String getBrand() {
return brand;
} public void setBrand(String brand) {
this.brand = brand;
}
}

  获取构造方法:

   /**
* 测试获取构造方法
*/
@Test
public void testGetConstructor() throws ClassNotFoundException {
Class<?> aClass = Class.forName("com.reflect.pojo.Product");
//获取构造器
Constructor<?>[] declaredConstructors = aClass.getDeclaredConstructors();
for (Constructor<?> declaredConstructor : declaredConstructors) {
System.out.println("declaredConstructor: [" + declaredConstructor + "]");
}
}

2、反射创建对象

1、 newInstance()

注意 : 只能够调用无参数的构造方法,无参数的构造方法必须是有权限被访问到的。

2、获得构造器对象之后,通过构造器来创建对象

   /**
* 测试反射创建对象的两种方法
*/
@Test
public void testCreateInstance() throws Exception {
//方法一 Class类中有对应的方法 newInstance()
Class<?> aClass = Class.forName("com.reflect.pojo.Product");
Product product = (Product) aClass.newInstance(); //方法二 获得构造器对象之后,通过构造器来创建对象
Constructor<?> constructor = aClass.getDeclaredConstructor();
Product product1 = (Product) constructor.newInstance();
}

3、获取方法

1、获取所有方法

  getMethods

  getDeclaredMethods

2、获取单个方法

  getMethod

  getDeclaredMethod

     /**
* 测试获取方法
*/
@Test
public void testGetMethods() throws Exception{
Class<?> aClass = Class.forName("com.reflect.pojo.Product"); //获取方法
Method[] declaredMethods = aClass.getDeclaredMethods();
for (int i = 0; i < declaredMethods.length; i++){
Method declaredMethod = declaredMethods[i];
//获取方法返回类型
Class<?> returnType = declaredMethod.getReturnType();
//输出方法返回类型
System.out.println("returnType: [" + returnType + "]");
//获取方法参数类型
Class<?>[] parameterTypes = declaredMethod.getParameterTypes();
for (Class parameterType: parameterTypes){
System.out.println("parameterType: [" + parameterType + "]");
}
//输出变量名称
System.out.println("i: " + i + " declaredMethod: ["+declaredMethod.getName() + "]");
}
}

4、获取字段(成员变量)

1、获取所有字段

  getFields、getDeclaredFields

2、获取单个字段

  getField、getDeclaredField

3、修改获取字段的值

  set(Object obj,Object value); 将指定对象变量上此 Field 对象表示的字段设置为指定的新值。

  get(Object obj);  返回指定对象(传入的obj)上此 Field 表示的字段的值。

     /**
* 获取字段
*/
@Test
public void testAPI() throws ClassNotFoundException {
//获取field
Class<?> aClass = Class.forName("com.reflect.pojo.Product");
//获取字段
Field[] declaredFields = aClass.getDeclaredFields();
for (Field df:declaredFields){
//获取字段类型
Class<?> type = df.getType();
System.out.println("type: [" + type + "]");
System.out.println(df);
}
}

5、通过反射调用方法

1、获得类对应的Class实例;

2、通过反射得到类中的指定的方法

3、通过反射(Method类)来调用方法

Method中的方法:

Object invoke(Object obj, Object... args)

obj: 调用的对象

args: 方法参数

     /**
* 反射调用方法
*/
@Test
public void testInvoke() throws Exception {
Product product = new Product();
product.setId(7);
product.setClassifyId(3);
product.setBrand("联想");
product.setProductName("G480笔记本"); //1.获取字节码
Class<?> aClass = product.getClass();
//2.获取属性
Field[] declaredFields = aClass.getDeclaredFields();
//3.获取属性数组
for (Field declaredField : declaredFields) {
//获取属性名
String fieldName = declaredField.getName();
//回去get方法字符串名
String methodName = "get" + toMethodName(fieldName);
//通过方法名称使用反射获取方法对象
Method method = aClass.getMethod(methodName);
//执行方法
Object invoke = method.invoke(product);
//装换字符串类型
String s = String.valueOf(invoke);
System.out.println(fieldName + "=" + s);
}
}

Java基础(十三)反射的更多相关文章

  1. 黑马程序员:Java基础总结----反射

    黑马程序员:Java基础总结 反射   ASP.Net+Android+IO开发 . .Net培训 .期待与您交流! 反射 反射的基石:Class类 Class类代表Java类,它的各个实例对象又分别 ...

  2. Java基础之一反射

    反射是框架设计的灵魂 (使用的前提条件:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码))   一.反射的概述 JAVA反射机制是在运行状态中,对于任意一个类,都能够 ...

  3. Java基础之—反射

    反射是框架设计的灵魂 (使用的前提条件:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码))   一.反射的概述 JAVA反射机制是在运行状态中,对于任意一个类,都能够 ...

  4. JAVA基础知识|反射

    一.理解反射 1.1.基础概念 反射:在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方法的功能称为ja ...

  5. java基础之反射机制

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

  6. java基础(十一 )-----反射——Java高级开发必须懂的

    本文我们通过一个实际的例子来演示反射在编程中的应用,可能之前大家对反射的学习,仅仅是停留在概念层面,不知道反射究竟应用在哪,所以是一头雾水.相信通过这篇教程,会让你对反射有一个更深层次的认知. 概念 ...

  7. java基础之反射---重要

    java反射: 反射是框架设计的灵魂 (使用的前提条件:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码)):   1:获取Class字节码文件对象的三种方式: /** ...

  8. 【Java基础】反射和注解

    前言 在Java中,反射机制和注解机制一直是一个很重要的概念,那么他们其中的原理是怎么样呢,我们不仅仅需要会使用,更要知其然而之所以然. 目录 反射机制 反射如何使用 注解定义 注解机制原理 注解如何 ...

  9. java基础篇---反射机制

    一.JAVA是动态语言吗? 一般而言,说到动态言,都是指在程序运行时允许改变程序结构或者变量类型,从这个观点看,JAVA和C++一样,都不是动态语言. 但JAVA它却有着一个非常突出的动态相关机制:反 ...

  10. Java 基础总结--反射的基本操作

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

随机推荐

  1. Java面试必问

    1. 图灵 1.1 聊聊哈希算法与HashMap 1)一个优秀的哈希算法有什么特点? 快速.不可逆.敏感性.低碰撞性 2)自己写一个Hash算法 取模 3)Java中的Hash算法 HashMap,侧 ...

  2. shell__常用命令__grep

    grep | zgrep (不用解压zip就能直接搜索) -i 不区分大小写 -I 忽略二进制文件 -R或r 递归文件目录 -c 计算找到的总数量 -n 显示行号 -v 显示不包含匹配文本的所有行 - ...

  3. css盒子模型基础,margin-top塌陷,元素溢出

    现在布局不用table,一般用盒子模型来布局,也就是通常说的div+css,一个页面就是多个盒子的拼接   一. 初识盒子模型   例子1,测试盒子各属性设置   <head> <s ...

  4. 20 行代码极速为 App 加上聊天功能

    现在很多 App 都需要集成 IM 功能,今天就为大家分享一下集成 IM 基本功能的步骤.本文内容以 JMessage 为例.极光 IM ( JMessage ) = 极光推送 ( JPush ) + ...

  5. 标准结构篇:4)EMC电磁兼容

    本章目的:电磁兼容EMC概念,及预防控制手段. 1.前言:电磁兼容EMC概述 电磁兼容是一门新兴的综合性学科.电磁兼容学科主要研究的是如何使在同一电磁环境下工作的各种电气电子设备和元器件都能正常工作, ...

  6. [转] 深入理解Java G1垃圾收集器

    [From] https://www.cnblogs.com/ASPNET2008/p/6496481.html 深入理解Java G1垃圾收集器 本文首先简单介绍了垃圾收集的常见方式,然后再分析了G ...

  7. SqlServer数据库《基本》

    数据库简单说就是行.列组成的二维表 把列称为字段.每一行数据成为记录,能标识每一行的唯一字段称为主键 查询数据表时,索引可以提高查询速度,但是索引同时会降低新增和更新数据时的速度,应为还要更新索引. ...

  8. Windows下代替自带cmd的开源软件cmder

    cmder cmder是一个增强型命令行工具,不仅可以使用windows下的所有命令,更爽的是可以使用linux的命令,shell命令 下载 Cmder官网 下载的时候,会有两个版本,分别是mini与 ...

  9. python安装方法

    1.下载Python安装包 2.配置环境变量 path=%path%;C:\Python27 3.安装pip 默认已安装 4.配置pip环境变量 path=%path%;C:\Python27\Scr ...

  10. PZ73H-PZ73X刀闸阀厂家,PZ73H-PZ73X刀闸阀价格 - 专题栏目 - 无极资讯网

    无极资讯网 首页 最新资讯 最新图集 最新标签   搜索 PZ73H-PZ73X刀闸阀 无极资讯网精心为您挑选了(PZ73H-PZ73X刀闸阀)信息,其中包含了(PZ73H-PZ73X刀闸阀)厂家,( ...