Java反射的简单入门
1.Class的简单介绍
Class类的类表示正在运行的Java应用程序中的类和接口。 枚举是一种类,一个注解是一种接口, 每个数组也属于一个反映为类对象的类,该对象由具有相同元素类型和维数的所有数组共享。 原始Java类型( boolean , byte , char , short , int , long , float和double ),和关键字void也表示为类对象。
摘自jdk1.8中文版,刚开始看可能不懂,现在逐句来解释一下。
第一句话:一个类被加载以后,JVM就会在内存中给创建一个对应类的Class对象。
第二句话:类型相同的对象,维数相同的数组(不管长度)共享的是同一个内存中的Class对象。
第三句话:上面这些原始的类型,也会在内存中有一个与之对象的Class对象。
package com.dingyu; import org.junit.Test; /**
* Class的简单使用方法
*
* @author 70241
*
*/
public class ClassDemo {
@Test
public void classTest1() {
try {
Class class1 = Class.forName("com.dingyu.User");// 第一种获取Class对象的方法
User user = new User();
Class class2 = user.getClass();// 第二种获取Class对象的方法
Class class3=User.class;//第三种获取Class对象的方法
System.out.println("接下来判断到底同一类的不同对象的Class对象是不是同一个:"
+ (class1.hashCode() == class2.hashCode()&&class1.hashCode() == class3.hashCode())); } catch (ClassNotFoundException e) {
e.printStackTrace();
}
} @Test
public void classTest2() {
String[] s1 = new String[10];
String[] s2 = new String[30];
String[][] s3 = new String[3][30];
System.out.println(s1.getClass().hashCode()==s2.getClass().hashCode());
System.out.println(s1.getClass().hashCode()==s3.getClass().hashCode()); }
}


2.Class获取类的属性,构造器,方法和注解的简单使用
package com.dingyu; import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method; import org.junit.Test; /**
* Class的简单用法
*
* @author dingyu
*
*/
public class ClassDemo02 { @Test
public void usingClass() throws Exception { Class userClass = Class.forName("com.dingyu.User"); // 获得类名
System.out.println(userClass.getName());// 获得全类名
System.out.println(userClass.getSimpleName());// 获得类名 // 获得属性
Field[] fields = userClass.getDeclaredFields();// 获得所有的属性
for (Field field : fields) {
System.out.println(field.getName());
} System.out.println(userClass.getDeclaredField("id").getName());// 获得指定的属性 // 获得方法
Method[] methods = userClass.getDeclaredMethods();// 获得所有的方法
for (Method method : methods) {
System.out.println(method.getName());
}
Method method = userClass.getDeclaredMethod("setId", int.class);// 获得指定的方法,前面方法名,后面方法的参数
System.out.println(method.getName()); // 获得构造器
Constructor[] constructors = userClass.getDeclaredConstructors();
System.out.println(constructors.length);
Constructor constructor = userClass.getDeclaredConstructor(int.class, String.class, int.class);// 获得指定的构造器,需要指定构造的参数
System.out.println(constructor.getName()); // 获得注解
Annotation[] annotations = userClass.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation);
}
// 指定注解名
MyAnnotation annotation = (MyAnnotation)userClass.getDeclaredAnnotation(MyAnnotation.class);
System.out.println(annotation);
}
}
3.Class动态的调用构造器,方法,修改属性
package com.dingyu; import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method; import org.junit.Test;
/**
* 使用反射动态的调用构造器,方法,修改属性
* @author 70241
*
*/
public class ClassDemo03 {
@Test
@SuppressWarnings("all")
public void usingClass() throws Exception {
Class class1 = Class.forName("com.dingyu.User"); //使用反射去调用构造器
User user1 = (User) class1.newInstance();//调用的是无参的 Constructor constructor = class1.getDeclaredConstructor(int.class,String.class,int.class);//获得有参的构造器
User user2 = (User) constructor.newInstance(04,"dingyu",20);//动态生成对象 //使用反射去调用方法
Method methodSetId = class1.getDeclaredMethod("setId",int.class);
methodSetId.invoke(user1, 02);//执行user1中的setId,后面是给的参数
System.out.println(user1.getId()); //使用反射去修改属性的值
Field field = class1.getDeclaredField("age");
field.setAccessible(true);//因为age是私有的,加上这句就表示这个属性不需要做安全检查
field.set(user1, 20);
System.out.println(field.get(user1));
System.out.println(user1.getAge()); }
}
4.反射获得带泛型的参数或返回值里泛型的的类型
package com.dingyu; import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Map;
/**
* 反射获得带泛型的参数或返回值里泛型的的类型
* @author dingyu
*
*/
public class ClassDemo04 {
public void test01(Map<Integer, String> map, String s) { } public Map<Integer, String> test02() {
return null;
} public static void main(String[] args) throws Exception {
//参数中带泛型的
Method method = ClassDemo04.class.getDeclaredMethod("test01", Map.class, String.class);
Type[] types = method.getGenericParameterTypes();// 返回一个 Type对象的数组, Type以声明顺序表示由该对象表示的可执行文件的形式参数类型
// 打印这些参数的类型
for (Type type : types) {
System.out.println(type.getTypeName());
if (type instanceof ParameterizedType) {// 如果是泛型的参数
Type[] actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments();// 获得泛型的的类型
for (Type type2 : actualTypeArguments) {
System.out.println(type2.getTypeName());
}
}
} //返回值中带泛型的
Method method02 = ClassDemo04.class.getDeclaredMethod("test02");
Type type = method02.getGenericReturnType();// 返回的类型
// 打印这些返回的类型
System.out.println(type.getTypeName());
if (type instanceof ParameterizedType) {// 如果是泛型的参数
Type[] actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments();// 获得泛型的的类型
for (Type type2 : actualTypeArguments) {
System.out.println(type2.getTypeName());
}
}
} }
Java反射的简单入门的更多相关文章
- Java的多线程 简单入门
Java的多线程 简单入门 首先能够先搞清楚什么是程序.进程.线程,以及它们之间的关系: 定义: 一 程序仅仅是一组指令的有序集合.它是静态的 二 进程是具有一定独立功能的程序关于某个数据集合上的一次 ...
- 通过java反射实现简单的关于MongoDB的对象关系映射(ORM).
通过阅读MongoDB 3.2.1的官方文档中关于java 编程发现最新的文档并没有实现对对象到Document的映射,所以自己有了利用反射实现简单的关系映射. 1.定义抽象类:AbstractMo ...
- Java中Redis简单入门
Redis是一个开源的,先进的 key-value 存储可用于构建高性能,可扩展的 Web 应用程序的解决方案. Redis官方网网站是:http://www.redis.io/,如下: Redis ...
- java反射机制简单实例
目录 Java反射 简单实例 @(目录) Java反射 Java语言允许通过程序化的方式间接对Class进行操作.Class文件由类装载器装载后,在JVM中将形成一份描述Class结构的元信息对象,通 ...
- Java反射机制简单使用
1.Java反射相关类所在package: java.lang.reflect.* 2.开始使用Reflection: 使用reflect相关类,遵循三个步骤: a.获取想要操作类的 java.lan ...
- Java反射机制 —— 简单了解
一.概述 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为jav ...
- java反射机制简单介绍
1.字节码.所谓的字节码就是当java虚拟机载入某个类的对象时,首先须要将硬盘中该类的源码编译成class文件的二进制代码(字节码),然后将class文件的字节码载入到内存中,之后再创建该类的对象 2 ...
- Java爬虫——Gecco简单入门程序(根据下一页一直爬数据)
为了完成作业,所以学习了一下爬虫Gecco,这个爬虫集合了以往所有的爬虫的特点,但是官方教程中关于Gecco的教程介绍的过于简单,本篇博客是根据原博客的地址修改的,原博客中只有程序的截图,而没有给出一 ...
- Java反射机制简单学习
java中除了基本数据类型,几乎都为对象.例如 Person p=new Person(); 这句语句表明了p是Person类的一个实例对象.但其实,Person也是一个实例对象,它是Class类的实 ...
随机推荐
- 【腾讯Bugly干货分享】iOS App 签名的原理
本文来自 WeRead 团队博客: http://wereadteam.github.io/ iOS 签名机制挺复杂,各种证书,Provisioning Profile,entitlements,Ce ...
- 包建强的培训课程(16):Android新技术入门和提高
@import url(/css/cuteeditor.css); Normal 0 10 pt 0 2 false false false EN-US ZH-CN X-NONE $([{£¥·‘“〈 ...
- 初探APT攻击
首发于i春秋 作者:joe 所属团队:Arctic Shell 团队博客地址:https://www.cnblogs.com/anbus/ 0x1:关于APT的相关介绍: APT是 ...
- 小白必读:闲话HTTP短连接中的Session和Token
本文引用了刘欣的文章,感谢原作者的分享. 1.引言 Http协议在现今主流的IM系统中拥有无可替代的重要性(在IM系统中用HTTP发起的连接被大家简称为http短连接),但Http作为传统互联网信息交 ...
- 使用MagicOnion实现gRPC
1.什么是gRPC 官方文档:https://grpc.io/docs/guides/index.html 2.什么是MagicOnion MagicOnion开源地址:https://github. ...
- 微信小程序web-view实例
微信小程序web-view实例 index.js //index.js //获取应用实例 const app = getApp() Page({ /** * 页面的初始数据 */ data: { }, ...
- 从零開始学Xamarin.Forms(一) 概述
Xamarin 读 "ˈzæmərin",是一个基于开源项目mono的可以使用C#开发的收费的跨平台(iOS.Android.Windows Phone.Mac)解决方式. ...
- VP9 vs H.265——下一代视频编码标准的王道之争
目前下一代主流的视频编码标准有 ITU-T VCEG 推出来的 H.265 和 Google 推出 VP9 . H.265 在 H.264 的基础上保留其中的部分技术,并对相关技术加以改进研发而成.新 ...
- 源码安装ELK-5.6.10版本
目录: 一.介绍 二.安装JDK 三.安装Elasticsearch 四.安装Kibana 五.安装Nginx 六.安装Logstash 七.安装Logstash-forwarder 八.测试 系统环 ...
- 基于Electron+.NET Core的前后端分离的跨平台桌面应用
Web做界面比原生桌面界面开发速度真心要快很多,而且组件也多. 分析: 1..NET Core和Electron都是跨平台的. 2.NET Core做后端很方便,但是没有GUI,Electron做桌面 ...