Java中的反射该如何使用?

1. 什么是反射

反射是一种功能强大且复杂的机制。Java反射说的是在运行状态中,对于任何一个类,我们都能够知道这个类有哪些方法和属性。对于任何一个对象,我们都能够对它的方法和属性进行调用。我们把这种动态获取对象信息和调用对象方法的功能称之为反射机制。

2. 反射可以用来做什么

反射能够分析类的能力,反射的机制十分强大,主要可以用来:

在运行时分析类的能力

在运行时查看对象

实现通用的数组操作代码

利用Method对象,实现C++中函数指针的功能

3. Class类

所谓的反射其实是获取类的字节码文件,也就是.class文件,而获取Class这个对象主要有三种方式:

getClass()函数、.class、forName()方法,代码如下:

package core.java;

import java.util.ArrayList;

public class Test {

public static void main(String[] args) throws ClassNotFoundException {

ArrayList<Integer> test = new ArrayList<>();

//第一种方法

Class a = test.getClass();

System.out.println(a);

//第二种方法

Class b = Test.class;

System.out.println(b);

//第三种方法

Class c = Class.forName("java.lang.Math");

System.out.println(c);

}

}

4. 利用反射分析类

在reflect包中有三个类:Field、Method和Constructor分别用于描述类的域、方法和构造器。这三个类都有一个叫做getName()的方法,用来返回项目的名称。Field类有一个getType方法,用来返回描述域所属类型的Class对象。这三个类共同有一个getModifiers的方法,他将返回一个整型数值,来描述修饰符的情况。可以使用Modifier类的静态方法分析其返回的整型数值,也可以使用其toString()方法将对应的修饰符打印出来。

Class类中的getFields、getMethods和getConstructors方法将分别返回类提供的public域、方法和构造器数组,其中包括超类的共有成员。

Class类中的getDeclareFields、getDeclareMethods和getDeclaredConstructors方法将分别返回类中声明的全部域、方法和构造器,其中包括私有和受保护的成员,但不包括超类的成员。

实例代码:

package core.java.reflect;

import java.util.*;

import java.lang.reflect.*;

public class ReflectionTest

{

public static void main(String[] args)

{

// 读取类名

String name;

if (args.length > 0) name = args[0];

else

{

Scanner in = new Scanner(System.in);

System.out.println("Enter class name (e.g. java.util.Date): ");

name = in.next();

}

try

{

Class cl = Class.forName(name);

Class supercl = cl.getSuperclass();

String modifiers = Modifier.toString(cl.getModifiers()); //打印修饰符

if (modifiers.length() > 0) System.out.print(modifiers + " ");

System.out.print("class " + name);

if (supercl != null && supercl != Object.class) System.out.print(" extends "

+ supercl.getName());//输出超类

System.out.print("\n{\n");

printConstructors(cl); //输出构造器数组

System.out.println();

printMethods(cl); //输出方法

System.out.println();

printFields(cl);  //输出域

System.out.println("}");

}

catch (ClassNotFoundException e)

{

e.printStackTrace();

}

System.exit(0);

}

public static void printConstructors(Class cl)

{

Constructor[] constructors = cl.getDeclaredConstructors(); //获取构造器数组

for (Constructor c : constructors)

{

String name = c.getName();

System.out.print("   ");

String modifiers = Modifier.toString(c.getModifiers()); //输出修饰符

if (modifiers.length() > 0) System.out.print(modifiers + " ");

System.out.print(name + "("); //构造器签名

// print parameter types

Class[] paramTypes = c.getParameterTypes(); //获取构造器参数数组

for (int j = 0; j < paramTypes.length; j++)

{

if (j > 0) System.out.print(", ");

System.out.print(paramTypes[j].getName());

}

System.out.println(");");

}

}

public static void printMethods(Class cl)

{

Method[] methods = cl.getDeclaredMethods();

for (Method m : methods)

{

Class retType = m.getReturnType(); //获取返回类型

String name = m.getName(); //方法名

System.out.print("   ");

String modifiers = Modifier.toString(m.getModifiers()); //输出修饰符

if (modifiers.length() > 0) System.out.print(modifiers + " ");

System.out.print(retType.getName() + " " + name + "(");

// print parameter types

Class[] paramTypes = m.getParameterTypes(); //获取参数数组

for (int j = 0; j < paramTypes.length; j++)

{

if (j > 0) System.out.print(", ");

System.out.print(paramTypes[j].getName());

}

System.out.println(");");

}

}

public static void printFields(Class cl)

{

Field[] fields = cl.getDeclaredFields(); //获取域数组

for (Field f : fields)

{

Class type = f.getType(); //获取参数类型

String name = f.getName(); //获取域名称

System.out.print("   ");

String modifiers = Modifier.toString(f.getModifiers()); //输出修饰符

if (modifiers.length() > 0) System.out.print(modifiers + " ");

System.out.println(type.getName() + " " + name + ";");

}

}

}

5、利用反射技术得到所有的构造函数

public class Test02 {

public static void main(String[] args) {

try {

Class clazz = Student.class;// 获取class对象

String name = clazz.getName();// 获得类的名称(全限定名)

Constructor<?>[] constructors = clazz.getDeclaredConstructors();// 返回指定参数类型的所有构造器

for (Constructor constructor : constructors) {

System.out.println(constructor);

}

} catch (SecurityException e) {

e.printStackTrace();

}

}

}

输出结果:

public com.etime2.Student()

public com.etime2.Student(java.lang.String,java.lang.Integer,java.lang.String)

备注:

getDeclaredConstructor()与getConstructor的区别

getDeclaredConstructor(Class<?>… parameterTypes)

这个方法会返回指定参数类型的所有构造器,包括public的和非public的,其中当然也包括private私有的。

getDeclaredConstructors()的返回结果就没有参数类型的过滤了。

getConstructor(Class<?>… parameterTypes)

这个方法返回的是上面方法返回结果的子集,外汇返佣只返回指定参数类型访问权限是public的构造器。

getConstructors()的返回结果同样也没有参数类型的过滤。

6、利用反射技术得到类的所有方法

public class Test03 {

public static void main(String[] args) {

try {

Class clazz = Class.forName("com.etime2.Student");// 获取类的class对象(加载和解析类的字节码,返回相应的class对象)

Method[] Methods = clazz.getDeclaredMethods();// 获取所有的方法,包括私有方法

for (Method method : Methods) {

String name = method.getName();// 获得类的名称(全限定名)

System.out.println(name);

}

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

}

}

输出结果:

getName

setName

sleep

getGender

getAge

setAge

setGender

7、利用反射技术得到类的所有字段

public class Test04 {

public static void main(String[] args) {

try {

Class clazz = Class.forName("com.etime2.Student");

Field[] fields = clazz.getDeclaredFields();// 获取所有的字段

for (Field field : fields) {

System.out.println("字段:" + field);

String name = field.getName();// 获得类的名称(全限定名)

System.out.println("名称:" + name);

Class<?> type = field.getType();// 获取变量的类型

System.out.println("类型:" + type);

int modifiers = field.getModifiers();// 获得类的修饰符

boolean public1 = Modifier.isPublic(modifiers);

boolean static1 = Modifier.isStatic(modifiers);

boolean final1 = Modifier.isFinal(modifiers);

System.out.println("public1=" + public1 + "  static1=" + static1 + "  final1=" + final1);

}

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

}

}

输出结果:

字段:private java.lang.String com.etime2.Student.name

名称:name

类型:class java.lang.String

public1=false  static1=false  final1=false

字段:private java.lang.Integer com.etime2.Student.age

名称:age

类型:class java.lang.Integer

public1=false  static1=false  final1=false

字段:private java.lang.String com.etime2.Student.gender

名称:gender

类型:class java.lang.String

public1=false  static1=false  final1=false

利用反射调用对象的私有方法(不完整)

public class Test05 {

public static void main(String[] args) {

try {

Class<?> clazz = Class.forName("com.etime2.Student");

Method method = clazz.getDeclaredMethod("sleep");

method.setAccessible(true);// 允许访问私有

Object newInstance = clazz.newInstance();// 调用无参构造函数创建对象

Student student = (Student) newInstance;

Object invoke = method.invoke(student);

System.out.println(invoke);

} catch (Exception e) {

e.printStackTrace();

}

}

}

运行结果:

上课时间打盹!

null

原文地址:https://www.cnblogs.com/benming/p/11548626.html

时间: 2024-10-12 23:12:18

Java中的反射该如何使用?的相关文章

java中利用反射机制绕开编译器对泛型的类型限制

首先看下面这个例子 public static void main(String[] args) { ArrayList<Integer> al1 = new ArrayList<Integer>(); al1.add(1); ArrayList<String> al2 = new ArrayList<String>(); al2.add("hello"); //int型链表和string型链表,结果为true System.out.pr

Java中的反射——(1)什么是反射

Java程序中的各个Java类属于同一类事物,描述这类事物的Java类名就是Class. public class ReflectTest { public static void main(String[] args) throws ClassNotFoundException { String str1 = "abc"; Class cls1 = String.class; Class cls2 = str1.getClass(); Class cls3 = Class.forNa

浅说Java中的反射机制(二)

写过一篇Java中的反射机制,不算是写,应该是抄了,因为那是别人写的,这一篇也是别人写的,摘抄如下: 引自于Java基础--反射机制的知识点梳理,作者醉眼识朦胧.(()为我手记) 什么是反射? 正常编译执行java文件时,会生成一个.class文件,反射就是一个反编译的过程,它可以通过.class文件得到一个java对象.一个类会有很多组成部分,比如成员变量.成员方法.构造方法等,反射可以通过加载类(加载类是个什么东西?一直搞不清楚),解剖出类的各个组成部分. 为什么要用反射? 我们需要访问一个

JAVA中的反射只获取属性的get方法

JAVA中的反射只获取属性的get方法 在开发过程中,我们经常需要获取类中某些属性的get方法,此时我们需要使用到反射,例如,我们在获得一个对象后,需要知道该对象的哪些属性有值,哪些没有值,方便我们后面的处理. 譬如在我们拼SQL语句时,就需要知道哪些字段为空或为NULL,此时我们在拼语句的时候需要剔除掉,若是我们采用一般的判断的办法,则会很复杂(需要处理好SQL中的AND关键字的有无 ),当然,我们也有另外的解决办法(例如将非空的键和值存入map中,再将map存入list集合中,然后循环集合做

关于JAVA中的反射机制的总结

JAVA中的反射机制是一种能够大大增强程序扩展性的技术.当一个程序封装完成后(生成exe文件),如果想要对该程序进行功能扩展,不用进行代码的从新修改(也不可能拿到源码),只要修改配置文件(一般是XML)就可以完成. 这样的程序为外部提供了一个接口,只要按照该接口的规则定义一个对象(功能),即可以为应用程序扩展该功能. 可以这样比喻,你买了一块电脑主板(封装好的程序),此时你想要添加一块声卡(要扩展的功能),此时只能够通过一个pci接口(应用程序提供的接口)来进行扩展.声卡的接口必须符合PCI的规

Java 中的反射机制

一.什么是Java中的反射: Reflection 是 Java 程序开发语言的特征之一,它允许运行中的 Java 程序对自身进行检查,或者说“自审”,并能直接操作程序的内部属性和方法.Java 的这一能力在实际应用中用得不是很多,但是在其它的程序设计语言中根本就不存在这一特性.例如,Pascal.C 或者 C++ 中就没有办法在程序中获得函数定义相关的信息.Reflection 是 Java 被视为动态(或准动态)语言的关键,允许程序于执行期 Reflection APIs 取得任何已知名称之

java中使用反射获取pojo(实体)类的全部字段值

说起反射.不得不说它实在是太强大了,通过反射就能够轻轻松松拿到各种东东,假设你想在项目中解除对某个类的依赖,能够考虑用反射. 今天跟大家分享的是通过java中的反射,获取pojo类的全部字段值. 为什么要做这个操作的呢?主要是为了重写实体类的toString方法.有人会说.直接重写toString方法.返回字段.toString()的字符串不就可以了. 这么做的确能够.可是假设你的pojo类有上百个,上千个,你还要一个一个改吗?所以我们须要从新的方向去解决. 由于我们全部的pojo类.都继承一个

java中的反射机制在Android开发中的用处

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制.      然而在android中Google很多的类的某些方法不让第三方应用去调用,通过java反射机制能把这些隐藏方法获取出来并调用,三方应用上我们就很方便的去用这些方法.      例如我们需要安全的杀死某个应用的服务和进程调用ActivityManager.forceStopPack

黑马程序员【java中的反射机制】

Java中的反射机制 ------- android培训.java培训.期待与您交流! ---------- java的反射机制是java的特性之一,反射机制是构建框架技术的基础所在,使用反射可以使程序更加灵活,避免将程序写死在代码里.相对于很多初学者只接触过java基础的人,反射还是一个很朦胧难懂的概念,下面我们就来说一下反射的一些应用. java反射机制是指在运行状态中,动态获取信息以及动态调用对象方法的功能.java反射有3个动态性质:1.运行时生成对象实例,2.运行期间调用发放,3.运行

第二篇 java中的反射

java中的反射 一.反射的概述 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性: 这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制.要想解剖一个类,必须先要获取到该类的字节码文件对象. 而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象. 1.创建实体类 1 public class User { 2 private int id; 3 pr