Java基础(九)--反射
什么是反射?
在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性
这种动态获取的信息以及动态调用对象的方法的功能称为反射机制。
反射的前提:
需要获取代表每个类的java.lang.class对象,对于HotSpot来说,这个class对象保存在在方法区,作为这个类的各种数据的访问入口
获取class对象的方式:
public static void main(String[] args) throws Exception{
//第一种,通过对象获取class对象
A a = new A();
Class aClass = a.getClass();
System.out.println(aClass.getName());
//第二种,通过类直接获取class对象
Class aClass1 = A.class;
System.out.println(aClass == aClass1);
//第三种,通过类的全限定名获取class对象(包名+类名)
Class aClass2 = Class.forName("com.it.exception.A");
System.out.println(aClass == aClass2);
}
PS: 一般使用第三种方式来获取
构造函数相关方法:
public class A {
public A(int i) {
System.out.println("A Constructor " + i);
}
public A() {
System.out.println("A Constructor No Parameter");
}
protected A(String name) {
System.out.println("A Constructor " + name);
}
private A(int i, String name) {
System.out.println("A Constructor " + i + " name " + name);
}
}
public static void main(String[] args) throws Exception{
Class aClass = Class.forName("com.it.exception.A");
//返回所有public构造函数
Constructor[] constructors1 = aClass.getConstructors();
for (Constructor constructor : constructors1) {
System.out.println(constructor);
}
System.out.println("----getConstructors---------");
//返回具体某种参数类型的public构造函数,参数也可以是null,表示无参构造器
Constructor constructor = aClass.getConstructor(int.class);
System.out.println(constructor);
System.out.println("----get int Constructors---------");
//返回所有构造函数,无论什么修饰符修饰
Constructor[] constructors2 = aClass.getDeclaredConstructors();
for (Constructor constructor1 : constructors2) {
System.out.println(constructor1);
}
System.out.println("----getDeclaredConstructors---------");
//返回具体某种参数类型的构造函数,无论什么修饰符修饰
Constructor constructor2 = aClass.getDeclaredConstructor(String.class);
System.out.println(constructor2);
System.out.println("----String getDeclaredConstructor---------");
}
结果:
public com.it.exception.A()
public com.it.exception.A(int)
----getConstructors---------
public com.it.exception.A(int)
----get int Constructors---------
private com.it.exception.A(int,java.lang.String)
protected com.it.exception.A(java.lang.String)
public com.it.exception.A()
public com.it.exception.A(int)
----getDeclaredConstructors---------
protected com.it.exception.A(java.lang.String)
getEnclosingConstructor:
public class Outter {
public void destination(String s) {
class Inner1 {
private String label;
public Inner1() {
System.out.println("abc");
}
public Inner1(String whereTo) {
this.label = whereTo;
}
}
Class aClass = new Inner1().getClass();
//获取局部或匿名内部类在定义时所在的构造器
System.out.println(aClass.getEnclosingConstructor());
}
public static void main(String[] args) {
Outter outter = new Outter();
outter.destination("aaa");
}
}
这里实验类局部内部类一直得到的是null,大家可以试一下
调用构造器:
constructor.newInstance(); //默认无参构造器
字段相关方法:
public class A {
private int id;
private String name;
public int sex;
}
public static void main(String[] args) throws Exception{
Class aClass = Class.forName("com.it.exception.A");
//获取所有public字段
Field[] fields = aClass.getFields();
for (Field field : fields) {
System.out.println(field);
}
//获取某个具体字段,这个字段必须是public修饰,否则会报错
Field field = aClass.getField("sex");
System.out.println(field);
//获取所有字段,无论修饰符
Field[] fields1 = aClass.getDeclaredFields();
for (Field field1 : fields1) {
System.out.println(field1);
}
//获取某个具体字段
Field field1 = aClass.getDeclaredField("id");
System.out.println(field1);
}
结果:
public int com.it.exception.A.sex
public int com.it.exception.A.sex
private int com.it.exception.A.id
private java.lang.String com.it.exception.A.name
public int com.it.exception.A.sex
private int com.it.exception.A.id
其余操作:
public static void main(String[] args) throws Exception{
Class aClass = Class.forName("com.it.exception.A");
Field field = aClass.getDeclaredField("name");
Object object = aClass.getDeclaredConstructor(null).newInstance();
field.setAccessible(true); //设置为true,private字段可以修改,私有字段必须设置为true,否则set字段会发生异常
field.set(object, "sam");//设置具体字段value
A a = (A)object;
System.out.println(a.toString());
}
结果:
A(id=0, name=sam, sex=0)
方法相关操作:
public class A {
private int id;
private String name;
public int sex;
public void add() {
System.out.println("add()");
}
private void del() {
System.out.println("del()");
}
public static void update() {
System.out.println("static update()");
}
}
public static void main(String[] args) throws Exception{
Class aClass = Class.forName("com.it.exception.A");
Method[] methods = aClass.getMethods();
//获取所有public字段
for (Method method : methods) {
System.out.println(method);
}
//获取某个具体方法,这个method必须是public修饰,否则会报错
Method method = aClass.getMethod("add", null);
System.out.println(method);
//获取所有字段,无论修饰符
Method[] methods1 = aClass.getDeclaredMethods();
for (Method method1 : methods1) {
System.out.println(method1);
}
//获取某个具体字段
Method method1 = aClass.getDeclaredMethod("del", null);
System.out.println(method1);
}
结果:已经省略默认继承object的相关方法
public void com.it.exception.A.add()
public static void com.it.exception.A.update() public void com.it.exception.A.add() public void com.it.exception.A.add()
public static void com.it.exception.A.update()
private void com.it.exception.A.del() private void com.it.exception.A.del()
其余操作:
private int del(int i) {
System.out.println("del(): " + i);
return i + 3;
}
public static void main(String[] args) throws Exception{
Class aClass = Class.forName("com.it.exception.A");
Object object = aClass.getDeclaredConstructor(null).newInstance();
Method method = aClass.getDeclaredMethod("del", int.class);
method.setAccessible(true);
Object object1 = method.invoke(object, 20);
System.out.println(object1);
}
结果:
del(): 20
23
其他:
public class A extends B implements C{
@Override
public void f() throws IOException {
System.out.println("f()");
}
}
public static void main(String[] args) throws Exception{
Class aClass = Class.forName("com.it.exception.A");
System.out.println(aClass.getSuperclass());// 获取父类Class对象
System.out.println(aClass.getClassLoader());// 获取类的加载器
System.out.println(aClass.getInterfaces()[0]);// 获取类的接口数组列表
A[] as = new A[1];
System.out.println(as.getClass().getComponentType());// 获取该数组的Class对象
System.out.println(aClass.getPackage().getName());// 获取包
}
结果:
class com.it.exception.B
sun.misc.Launcher$AppClassLoader@18b4aac2
interface com.it.exception.C
class com.it.exception.A
com.it.exception
通过反射越过泛型检查
public static void main(String[] args) throws Exception{
ArrayList<String> list = new ArrayList<>();
list.add("a");
list.add("b");
// List<String> list = Arrays.asList("a", "b");
Class aClass = list.getClass();
Method method = aClass.getMethod("add", Object.class);
method.invoke(list, 20);
System.out.println(list);
// list.forEach(s -> {
// System.out.println(s);
// });
}
结果:List<String> list = Arrays.asList("a", "b");然后执行invoke()会报错的,也不要使用foreach也会报错(ClassCastException)
Java基础(九)--反射的更多相关文章
- 黑马程序员:Java基础总结----反射
黑马程序员:Java基础总结 反射 ASP.Net+Android+IO开发 . .Net培训 .期待与您交流! 反射 反射的基石:Class类 Class类代表Java类,它的各个实例对象又分别 ...
- Java基础九--抽象类
Java基础九--抽象类 一.抽象类介绍 /*抽象类:抽象:笼统,模糊,看不懂!不具体. 特点:1,方法只有声明没有实现时,该方法就是抽象方法,需要被abstract修饰. 抽象方法必须定义在抽象类中 ...
- 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中,反射机制和注解机制一直是一个很重要的概念,那么他们其中的原理是怎么样呢,我们不仅仅需要会使用,更要知其然而之所以然. 目录 反射机制 反射如何使用 注解定义 注解机制原理 注解如何 ...
随机推荐
- Codeforces 216D Spider's Web 树状数组+模拟
题目链接:http://codeforces.com/problemset/problem/216/D 题意: 对于一个梯形区域,假设梯形左边的点数!=梯形右边的点数,那么这个梯形为红色.否则为绿色, ...
- 【WinHec启发录】透过Windows 10技术布局,谈微软王者归来
每一个时代都有王者,王者的成功,往往是由于恰逢其时地公布了一个成功的产品(具有里程碑意义,划时代的产品).Windows 95的成功标示着微软是PC时代的王者:WinXP的成功标示着微软是互联网时代的 ...
- 图像处理之基础---yuv420及其rgb,bayer, yuv, RGB的相互转换详解
YUV格式解析1(播放器——project2) 根据板卡api设计实现yuv420格式的视频播放器 打开*.mp4;*.264类型的文件,实现其播放. 使用的视频格式是YUV420格式 YUV格式 ...
- J2SE基础:11.异常处理
1:异常的概念: 异常是程序在执行时发生的事件(异常发生在执行期间). 程序出现错误.打断原本的运行流程. 2:Java中处理异常. 在Java中.异常被封装成一个对象.(属性和方法) 3:异常产生 ...
- 代理ip 测试
Line #1218 : 101.232.208.245 - - [16/Jan/2018:02:47:34 +0800] "GET /?xltestdesfs HTTP/1.1" ...
- C语言8大经典排序算法(2)
二.插入类排序 插入排序(Insertion Sort)的基本思想是:每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子文件中的适当位置,直到全部记录插入完成为止. 插入排序一般意义上有两 ...
- sql 2005 win7 64 数据引擎
有个箭头,下拉,选择服务器名(就是本机的名称),如果没有就选择浏览更多,看能搜索出不还没的话就手动输入localhost
- bzoj4195 [Noi2015]程序自动分析——并查集
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4195 突然在这道大水题上WA了半天... 思路很简单,离线处理询问,先把 = 的都加到并查集 ...
- 如何给自己的博客上添加个flash宠物插件
最近在一些博主的博客上看到一些小宠物的挂件,很有趣,访客到了网站后可以耍耍小宠物,增加网站的趣味性,在功能强大的博客系统上看到有这样的小宠物挂件还是蛮有趣的. 多次差找资料后,终于在http://ww ...
- MSP430:实时时钟-DS1302
/* * DS1302.h * * Created on: 2013-11-27 * Author: Allen */ #ifndef DS1302_H_ #define DS1302_H_ #inc ...