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反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为 ...
随机推荐
- ocp最新考试题库:052新考题及答案整理-36
36.Which two are true about roles? A) A role can be granted a combination of system and object privi ...
- “全栈2019”Java第十七章:赋值运算符和算术运算符
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- 关于Socket通讯中的Close_wait状态
关于Socket通讯中的Close_wait状态 文/转 编辑 编者按:使用Socket通讯,有时我们查看端口状态的时候,经常会发现Socket处于close_wait状态,从而影响系统性能,此文或许 ...
- 对xaml的深入探究(补交作业)
首先,下结论,看完那个外国老师的视频后,5%左右听懂了,分享给大家: 1.理解一下,xaml是特殊的xml,我们可以从代码语法看出,xaml中的打码很类似与html和xml的代码. 2.xaml.cs ...
- POJ3666 Making the Grade
POJ3666 Making the Grade 题意: 给定一个长度为n的序列A,构造一个长度为n的序列B,满足b非严格单调,并且最小化S=∑i=1N |Ai-Bi|,求出这个最小值S,1<= ...
- 通过Maven简单搭建SSM框架
创建Maven就不用多说了,下面直接看Pom.xml里面的依赖吧 <properties> <!-- spring版本号 --> <spring.version>5 ...
- PHP将多维数组变成一维数组
function reduceArray($array) { $return = []; array_walk_recursive($array, function ($x) use (&$r ...
- HTML中title前面小图标和网站收藏现实的图标
网站上的logo实际上是一个“favicon.ico”图片.实现步骤:第一步:制作favicon.ico,大小为16*16毫米:第二步:将“favicon.ico”放到项目的根路径下. 第三步:在所有 ...
- 第二章C++实验
2-28 (1)用if else 语句 #include<iostream> using namespace std; int main(){ char alphabet; while ( ...
- rocketmq sql解析过滤
activemq rocketmq kafka robbitmq 公司 apache alibaba LinkedIn Pivotal 编写语言 java Erlang 客户端支持 其他协议支持 mq ...