一、反射

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. 实用的bash别名和函数

    本文来自于:程序师 作为一个命令行探索者,你或许发现你自己一遍又一遍重复同样的命令.如果你总是用ssh进入到同一台电脑,如果你总是将一连串命令连接起来,如果你总是用同样的参数运行一个程序,你也许希望在 ...

  2. mysqldump导出数据不带时区信息的问题

    今天在导出数据时,发现所有timestamp字段都不带时区信息,因为我在东8区,导出的数据中所有时间都提早了8个小时 首先先看表的字段和数据 CREATE TABLE IF NOT EXISTS `a ...

  3. 追随自己的价值观:用研经理 Anne Diaz 职业探索之路

    『漫谈』系列聚焦了人性脆弱面的价值.每期的对话嘉宾可能是爱彼迎设计团队的成员,也可能来自设计界的其他领域.对话主题都是我们在工作中很少讨论的话题. 这些话题涉及不同方面,比如失败.人生道路.冲突.成长 ...

  4. 万事不求人系列之-智能点餐算法实现-JavaScript实现智能点餐

    作为一个成长中的架构师,编码能力是万不能停止的,这个算法是之前在上一家单位帮助同事们自助订餐写的,纯爱好自己码敲的,刚好这段时间重新整理代码,发现了它,分享给大家,请大家品评指教. 使用场景介绍:随着 ...

  5. ARC初步介绍

    [转载自 http://onevcat.com/2012/06/arc-hand-by-hand/] 手把手教你ARC——iOS/Mac开发ARC入门和使用 Revolution of Objecti ...

  6. babel初学教程

    babel安装 安装前你需要安装node.js和npm以及gulp三个包. 然后执行以下命令 $ npm init 然后在安装 babel和babel-core两个包 $ npm install -- ...

  7. KVO 使用及原理

    KVO的基本原理大概是这样的   当一个对象被观察时, 系统会新建一个子类NSNotifying_A ,在子类中重写了对象被观察属性的 set方法,  并且改变了该对象的 isa 指针的指向(指向了新 ...

  8. [NodeJS]Jenkins-cli

    使用npm 包nestor 触发jenkins job, 达到命令行管理Jenkins功能. 1. install nestor : npm install -g nestor 2. set JENK ...

  9. 基础篇:3.4)3d模型绘制的好坏会影响产品合格率(注意点)

    本章目的:为了量产品的产能与合格率,重视3d图纸. 1.前言 作者希望本文能引起重视,是那些刚入行业的菜鸟: 还有只用2d图纸,便能绘制出能量产合格品的前辈大牛工程师. 2.3d图纸不合格的现状及典型 ...

  10. [蓝桥杯][2016年第七届真题]路径之谜(dfs)

    题目描述 小明冒充X星球的骑士,进入了一个奇怪的城堡. 城堡里边什么都没有,只有方形石头铺成的地面. 假设城堡地面是 n x n 个方格.[如图1.png]所示. 按习俗,骑士要从西北角走到东南角. ...