Spring基础之 反射(Reflection)
1.了解Class
package com.inspire.reflection.Class_api; import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method; public class ClassUtils {
public static void main(String[] args) {
String s="abc";
printclassFieldMessage(s);
printClassMethodMessage(s);
}
/**
* 打印类的信息,成员方法
* @param obj 该对象所属类的信息
*/
public static void printClassMethodMessage(Object obj){
//获取类的信息,获取类的类类型
Class c1=obj.getClass();//传递的哪个子类的对象,c就是该子类的类类型
//获取类的名称
System.out.println("类名是:"+c1.getName());
//获取方法
/*
Method类,方法的对象
一个成员方法就是一个Method对象
getMethods方法获取的是所有的public的方法,包括父类继承而来的
getDeclaredMethods方法获取的是所有该类自己定义的方法。不问访问权限
*/
Method[] methods=c1.getMethods();
// Method[] method=c1.getDeclaredMethods();
for (int i = 0; i <methods.length ; i++) {
//获取方法的返回值类型的类类型(比如返回String类型,返回的是String.class)
Class returnType=methods[i].getReturnType();
System.out.print(returnType.getName()+" "); //获取方法的名称
System.out.print(methods[i].getName()+"("); //获取参数类型 获取的是参数列表类型的类类型
Class[] paramType=methods[i].getParameterTypes(); for (Class c:paramType) {
System.out.print(c.getName()+",");
}
System.out.println(")");
}
}
/**
* 打印类的信息,成员变量
* @param obj
*/
public static void printclassFieldMessage(Object obj) {
//获取成员变量
/**
* 成员变量也是对象
* java.lang.reflect.Field
* Field封装了关于成员变量的操作
* getFields方法获取的是所有的public的成员变量信息
* getDeclaredFields()获取的是该类自己声明的成员信息(public/private)
*/
Class c1=obj.getClass();//传递的哪个子类的对象,c就是该子类的类类型
//Field[] fields=c1.getFields();
Field[] fields=c1.getDeclaredFields();
for (Field f:fields) {
//得到成员变量类型的类类型
Class fieldType=f.getType();
//得到成员变量的名称
String typeName=f.getName();
System.out.println(typeName+" "+fieldType);
}
}
/**
* 打印对象的构造函数的信息
* @param obj
*/
public static void printClassConMessage(Object obj){
Class c=obj.getClass();
/*
构造函数也是对象
java.lang.Constructor中封装了构造函数的信息
getDeclaredConstructor获取自己声明的构造函数
*/
Constructor[] constructors=c.getDeclaredConstructors();
//Constructor[] constructors=c.getConstructors();
for (Constructor constructor:constructors) {
System.out.println(constructor.getName()+"(");
//获取构造函数的参数列表
Class[] paramType=constructor.getParameterTypes();
for (Class c1:paramType) {
System.out.print(c1.getName()+",");
}
System.out.println(")");
}
}
}
2.获取一个类的类对象
(1).定义一个类
public class Student {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
private int age;
}
(2).获取类对象
public class ClassDemo1 {
public static void main(String[] args) {
//Student的实例对象如何表示?
// Student student=new Student();
/*Student也是实例对象,是Class类的实例对象。如何表示?
任何一个类都是Class类的实例对象,都有三种表示方法
*/
//方式一:任何一个类都有一个隐含的静态成员class
Class c1=Student.class;
//方式二:已知该类的对象,通过getClass方法
Student student=new Student();
Class c2=student.getClass();
/*
c1,c2表示了Student类的类类型(Class type)
万事万物皆对象
类也是对象,是Class类的实例对象
这个对象我们称为该类的类类型
*/
//c1,c2都代表了Student类的类类型,一个类只可能是Class类的一个实例对象
System.out.println(c1==c2); //true
//方式三:
try {
Class c3=Class.forName("com.inspire.reflection.Class_object.Student");
System.out.println(c2==c3); //true
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
/*
有了类的类类型,我们可以通过类类型创建该类的对象.即通过c1,c2,c3创建对象
*/
try {
Student student1= (Student) c1.newInstance();
//调用方法
student1.getAge();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
3.通过反射调用方法
public class Printer {
public void printA(){
System.out.println("无参的方法..........");
}
public void printA(int a,int b){
System.out.println(a+":"+b);
}
}
public class MethodDemo {
public static void main(String[] args) {
Printer printer=new Printer();
Class c=printer.getClass();
try {
//获取方法
Method method= c.getDeclaredMethod("printA", int.class, int.class);//获取自己声明的方法
//c.getMethod("printA", int.class, int.class);//获取public的方法
//方法的反射操作
method.invoke(printer,1,3); //放回方法的返回值
System.out.println("=========================");
Method method1=c.getDeclaredMethod("printA");
method1.invoke(printer);
} catch (Exception e) {
e.printStackTrace();
}
}
}
4.通过反射理解泛型
java中泛型是防止错误输入的。只在编译时有效。编译之后集合的泛型是去泛型化的
public static void main(String[] args){
ArrayList<String> list1=new ArrayList<String>();
list1.add("hello");
ArrayList list2=new ArrayList<String>();
//System.out.println(c1==c2);//结果为true,说明编译之后集合的泛型是去泛型化的
Class c2=list1.getClass();
try {
Method method=c2.getMethod("add", Object.class);
//注意这里:虽然上面定义list1时是String类型的,但是这里可以加入int类型的数据
method.invoke(list1,100);
System.out.println(list1.size());
System.out.println(list1);//不能用foreach遍历,类型不一样了
} catch (Exception e) {
e.printStackTrace();
}
}
Spring基础之 反射(Reflection)的更多相关文章
- Spring学习笔记(二)Spring基础AOP、IOC
Spring AOP 1. 代理模式 1.1. 静态代理 程序中经常需要为某些动作或事件作下记录,以便在事后检测或作为排错的依据,先看一个简单的例子: import java.util.logging ...
- .NET 反射(Reflection)
这节讲一下.NET 中的一个技术:反射(Reflection). 反射是一种很重要的技术,它可以在程序运行时,动态的获取类的实例,并调用实例中的任何方法.它就像一面镜子,映射出一个类的所有细节. ...
- [.net 面向对象程序设计进阶] (21) 反射(Reflection)(下)设计模式中利用反射解耦
[.net 面向对象程序设计进阶] (21) 反射(Reflection)(下)设计模式中利用反射解耦 本节导读:上篇文章简单介绍了.NET面向对象中一个重要的技术反射的基本应用,它可以让我们动态的调 ...
- [.net 面向对象程序设计进阶] (20) 反射(Reflection)(上)利用反射技术实现动态编程
[.net 面向对象程序设计进阶] (20) 反射(Reflection)(上)利用反射技术实现动态编程 本节导读:本节主要介绍什么是.NET反射特性,.NET反射能为我们做些什么,最后介绍几种常用的 ...
- [整理]C#反射(Reflection)详解
本人理解: 装配件:Assembly(程序集) 晚绑定:后期绑定 MSDN:反射(C# 编程指南) -----------------原文如下-------- 1. 什么是反射2. 命名空间与装配件的 ...
- 代理(Proxy)和反射(Reflection)
前面的话 ES5和ES6致力于为开发者提供JS已有却不可调用的功能.例如在ES5出现以前,JS环境中的对象包含许多不可枚举和不可写的属性,但开发者不能定义自己的不可枚举或不可写属性,于是ES5引入了O ...
- Spring基础系列-容器启动流程(1)
原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9870339.html 概述 我说的容器启动流程涉及两种情况,SSM开发模式和Spri ...
- Spring基础系列--AOP织入逻辑跟踪
原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9619910.html 其实在之前的源码解读里面,关于织入的部分并没有说清楚,那些前置.后 ...
- 第65节:Java后端的学习之Spring基础
Java后端的学习之Spring基础 如果要学习spring,那么什么是框架,spring又是什么呢?学习spring中的ioc和bean,以及aop,IOC,Bean,AOP,(配置,注解,api) ...
随机推荐
- win10系统安装两个版本的python,该怎么安装Django
最近遇到一个问题,系统上安装了python2,7 和python3.5两个版本,然后使用命令:pip install Django 安装Django后却发现以下情况: Traceback (most ...
- MongoDB 4.6.1 c++ driver 编译
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/sheismylife/article/details/25512251 这个版本号已经和之前不一样了 ...
- 【剑指offer】推断二叉树平衡
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/mmc_maodun/article/details/27242575 转载请注明出处:http:// ...
- P1802 5倍经验日(01背包问题,水题)
题目背景 现在乐斗有活动了!每打一个人可以获得5倍经验!absi2011却无奈的看着那一些比他等级高的好友,想着能否把他们干掉.干掉能拿不少经验的. 题目描述 现在absi2011拿出了x个迷你装药物 ...
- Qt+Qgis二次开发:在状态条显示当前鼠标坐标
1 概述 鼠标在地图上移动,需要实时获取当前坐标位置.2 原理 从当前位置获取视口坐标后,实时转换为地图坐标.3 方法 处理鼠标位置,必须获取鼠标的当前坐标.但是Qt的鼠标事件由QgsMapCanv ...
- centos7环境搭建
1. tar命令安装 yum install -y tar 2. jdk8下载 wget --no-check-certificate --no-cookies --header "Cook ...
- springboot2.0添加logback
程序代码 import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class PreFilter extends ZuulFil ...
- awk 内置函数列表
1.gsub要在整个记录中替换一个字符串为另一个,使用正则表达式格式,/目标模式/,替换模式/.例如改变学生序号4842到4899:$ awk 'gsub('4842/, 4899) {print $ ...
- CF1106F Lunar New Year and a Recursive Sequence 原根、矩阵快速幂、BSGS
传送门 好久没写数论题了写一次调了1h 首先发现递推式是一个乘方的形式,线性递推和矩阵快速幂似乎都做不了,那么是否能够把乘方运算变成加法运算和乘法运算呢? 使用原根!学过\(NTT\)的都知道\(99 ...
- 校内模拟赛 Zbq's Music Challenge
Zbq's Music Challenge 题意: 一个长度为n的序列,每个位置可能是1或者0,1的概率是$p_i$.对于一个序列$S$,它的得分是 $$BasicScore=A\times \sum ...