Java基础(十三)反射
一、反射
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基础(十三)反射的更多相关文章
- 黑马程序员:Java基础总结----反射
黑马程序员:Java基础总结 反射 ASP.Net+Android+IO开发 . .Net培训 .期待与您交流! 反射 反射的基石:Class类 Class类代表Java类,它的各个实例对象又分别 ...
- Java基础之一反射
反射是框架设计的灵魂 (使用的前提条件:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码)) 一.反射的概述 JAVA反射机制是在运行状态中,对于任意一个类,都能够 ...
- Java基础之—反射
反射是框架设计的灵魂 (使用的前提条件:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码)) 一.反射的概述 JAVA反射机制是在运行状态中,对于任意一个类,都能够 ...
- JAVA基础知识|反射
一.理解反射 1.1.基础概念 反射:在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方法的功能称为ja ...
- java基础之反射机制
一.概念 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为jav ...
- java基础(十一 )-----反射——Java高级开发必须懂的
本文我们通过一个实际的例子来演示反射在编程中的应用,可能之前大家对反射的学习,仅仅是停留在概念层面,不知道反射究竟应用在哪,所以是一头雾水.相信通过这篇教程,会让你对反射有一个更深层次的认知. 概念 ...
- java基础之反射---重要
java反射: 反射是框架设计的灵魂 (使用的前提条件:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码)): 1:获取Class字节码文件对象的三种方式: /** ...
- 【Java基础】反射和注解
前言 在Java中,反射机制和注解机制一直是一个很重要的概念,那么他们其中的原理是怎么样呢,我们不仅仅需要会使用,更要知其然而之所以然. 目录 反射机制 反射如何使用 注解定义 注解机制原理 注解如何 ...
- java基础篇---反射机制
一.JAVA是动态语言吗? 一般而言,说到动态言,都是指在程序运行时允许改变程序结构或者变量类型,从这个观点看,JAVA和C++一样,都不是动态语言. 但JAVA它却有着一个非常突出的动态相关机制:反 ...
- Java 基础总结--反射的基本操作
一.反射的概念 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为 ...
随机推荐
- 【后缀数组之height数组】
模板奉上 int rank[maxn],height[maxn]; void calheight(int *r,int *sa,int n) { ; ;i<=n;i++) rank[sa[i]] ...
- 小记 Linux 之 Vim
小记 Linux 之 Vim 使用vim用来进行文本流查询,是非常重要的部分. 技巧一:使用 '#' 系统将列出文档相同字符,在代码时很重要. 技巧二:使用 ']I' 具体操作是先使用 ? 或 \ 进 ...
- java集合类学习笔记之HashMap
1.简述 HashMap是java语言中非常典型的数据结构,也是我们平常用的最多的的集合类之一.它的底层是通过一个单向链表(Node<k,v>)数组(也称之为桶bucket,数组的长度也叫 ...
- Determining the Size of a Class Object---sizeof(class)---By Girish Shetty
There are many factors that decide the size of an object of a class in C++. These factors are: Size ...
- 基础篇:6.4)形位公差-基准 Datum
本章目标:了解形位公差基准及运用. 1.定义: 基准 — 与被测要素有关且用来定义其几何位置关系的一个几何理想要素(如轴线.直线.平面等): — 可由零件上的一个或多个基准要素构成. 模拟基准要素 ...
- acl权限使用
1.acl的设置技巧 *setfacl 用法: setfactl [-bkRd] [{-m|-x} acl参数] 目标文件名 -m:设置后续的acl参数给文件使用,不可与-x合用 -x:删除后续的ac ...
- java 接口的学习
1 什么是接口 接口是一种引用数据类型.使用interface声明接口,形式: public interface 接口名称{} 1.1.1 接口的特性 [1] 接口中可以声明属性.接口中定义的所 ...
- 小y的质数
题目链接:https://ac.nowcoder.com/acm/contest/634/C 链接:https://ac.nowcoder.com/acm/contest/634/C来源:牛客网 题目 ...
- Unity5 2D Animation
1. 所有的动画保存在 .anim 后缀的文件里.2. Animation 标签用来编辑一堆 Animation clip,每一个clip是一个图片序列,也就是动图.动画的最小控制单位就是clip,一 ...
- springboot+自定义注解实现灵活的切面配置
利用aop我们可以实现业务代码与系统级服务例如日志记录.事务及安全相关业务的解耦,使我们的业务代码更加干净整洁. 最近在做数据权限方面的东西,考虑使用切面对用户访问进行拦截,进而确认用户是否对当前数据 ...