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类的实 ...
随机推荐
- 解决jenkins控制台中文乱码问题
1,进入[系统管理]->[系统设置]->全局属性:KEY: LANG; VALUE:zh.CH.UTF-8 2,修改Jenkins.xml文件 在Jenkins安装目录下找到jenkins ...
- Jenkins可用环境变量列表以及环境变量的使用(Shell/Command/Maven/Ant)
一.可用环境变量列表(以下来自google翻译): BRANCH_NAME 对于多分支项目,这将被设置为正在构建的分支的名称,例如,如果您希望从而master不是从特征分支部署到生产. CHANGE_ ...
- Javascript高级编程学习笔记(17)—— 引用类型(6)基本包装类
基本包装类 基本包装类这个概念或许有的小伙伴没有听说过 但是小伙伴们有没有想过,为什么基本数据类型的实例也有方法呢? 其实这些方法都来自基本包装类型 这是JS为了方便操作基础数据类型而创建的特殊引用类 ...
- JS创建对象,数组,函数的三种方式
害怕自己忘记,简单总结一下 创建对象的3种方法 ①:创建一个空对象 var obj = {}; ②:对象字面量 var obj = { name: "Tom", age: 27 ...
- Ubuntu下安装和使用开源的tts软件Flite
Flite是什么? Flite是一个小型.快速的TTS系统,是festival的C版本,可用于嵌入式系统,支持WinCE.Palm OS 等. 下载方法: wget http://www.festvo ...
- ubuntu 16.04 下安装NVDIA的库(CUDA+CUDNN)
立志学习神经网络的同学,为了让它能够跑快一点,估计英伟达的GPU是要折腾一番的. 首先看一下什么是CUDA ? CUDA(Compute Unified Device Architecture),是显 ...
- slf4j日志门面担当
一.简介 slf4j主要是为了给Java日志访问提供一个标准.规范的API框架,其主要意义在于提供接口,具体的实现可以交由其他日志框架,例如log4j和logback等.当然slf4j自己也提供了功能 ...
- [学习笔记]利用e-debug和GetWindowTextA破解CM课件
本课是针对注册时候的报错弹窗不是信息框MessageBox,而是窗体的情况 首先打开课件看一下 既然课件是个易语言程序,那使用E-DEBUG试试 E-DEBUG打开课件,点击“start”,课件弹出登 ...
- python之连接oracle模块(cx_Oracle)
cx_Oracle模块下载地址如下: https://pypi.python.org/pypi/cx_Oracle/5.2.1#downloads 安装好之后就可以使用了,具体使用如下 #!/usr/ ...
- MySQL 分支的选择:Percona 还是 MariaDB
原文:https://www.biaodianfu.com/mysql-percona-or-mariadb.html 在MySQL被Oracle收购以后,越来越多的人对于MySQL的前景表示了担忧, ...