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) ...
随机推荐
- 【BZOJ3930】选数
[BZOJ3930]选数 Description 我们知道,从区间[L,H](L和H为整数)中选取N个整数,总共有(H-L+1)^N种方案.小z很好奇这样选出的数的最大公约数的规律,他决定对每种方案选 ...
- php结合redis高并发下,悲观锁解决数据二次写入
悲观锁 在悲观锁的情况下,为了保证事务的隔离性,就须要一致性锁定读.读取数据时给加锁,其他事务无法改动这些数据.改动删除数据时也要加锁,其他事务无法读取这些数据. 在做数据缓存的时候,通常都是把数据从 ...
- PHP开发小技巧①①—php实现手机号码显示部分
从个人信息保护性的角度来讲,我们在开发过程中总会想办法去保护用户的一些个人信息.就如本篇博文所讲,我们有时会将用户的手机号码只显示出部分,这是很多网站都有做的功能.这个功能实现起来也是特别的简单,只需 ...
- (二 -2) 天猫精灵接入Home Assistant-自动发现Mqtt设备
参考中文教程: https://www.hachina.io/docs/7230.html 英文官网 两个温度传感器:https://www.home-assistant.io/docs/mqtt/ ...
- 2017-2018-2 20155314《网络对抗技术》Exp6 信息搜集与漏洞扫描
2017-2018-2 20155314<网络对抗技术>Exp6 信息搜集与漏洞扫描 目录 实验目标 实验内容 实验环境 基础问题回答 预备知识 实验步骤 1 信息搜集 1.1 外围信息搜 ...
- go标准库的学习-fmt
参考https://studygolang.com/pkgdoc 导入方式: import "fmt" mt包实现了类似C语言printf和scanf的格式化I/O.格式化动作(' ...
- go标准库的学习-mime/multipart
参考:https://studygolang.com/pkgdoc 导入方式: import "mime/multipart" multipart实现了MIME的multipart ...
- go标准库的学习-crypto/md5
参考:https://studygolang.com/pkgdoc 导入方式: import "crypto/md5" md5包实现了MD5哈希算法,参见RFC 1321. Con ...
- rsyslog和logrotate服务
参考: http://www.lampbo.org/others/opensource/rsyslog-config-file-detail.html http://bangerlee.blog.ch ...
- docker安装与卸载
文章转自:https://www.cnblogs.com/yufeng218/p/8370670.html (EE安装) https://blog.csdn.net/jxyzh11/article/ ...