Java复习总结——详细理解Java反射机制

时间:2022-08-24 14:22:03

Java复习总结——详细理解Java反射机制

反射是什么

反射的作用用一句简单的话来讲就是可以对代码进行操作的代码,这个特性经常在被用于创建JavaBean中,通常造*的人会用到这个特性,而应用程序员用到这个特性的场景则较少。

能够分析类能力的程序就叫做反射,简单来说就是可以对代码进行操作的代码。反射机制的功能极为强大,可以用来:

  • 在运行时分析类的能力
  • 在运行时查看对象
  • 实现通用的数组操作代码
  • 利用Method对象来实现方法

从获取Class类开始

在程序运行期间,Java运行时系统始终为所有的对象维护一个被称为运行时的类型标识。这个信息跟踪着每个对象所属的类。这个类的获取方式有以下三种:

  1. 使用Object类中的getClass()方法来返回一个Class类的实例

    User user;
    Class userClass = user.getClass();
  2. 我们可以使用Class类的getName()方法来获取包含包名在内的类名。同样的,在已知这个名字的情况下,我们可以使用静态方法forName()获得类名对应的Class对象

Random generator = new Random();
Class randomClass = generator.getClass();
//className = "java.util.Random"
String className = randomClass.getName();
//第二种方式获取
Class newRandomClass = Class.forName(className);
  1. 获得Class类对象的第三种方法很简单,如果T是任意的Java类型(或者void关键字),T.class将代表匹配的类对象。例如:
Class randomClass = Random.class;
Class intClass = int.class;
Class doubleClass = Double[].class;

如果我们想要创建一个类的实例,可以使用newInstance()方法来动态创建:

String s = "java.util.Random";
Object m = Class.forName(s).newInstance();

构造函数的反射

获得构造函数的方法

    //根据指定参数获得public构造器
Constructor getConstructor(Class[] params);
//获得public的所有构造器
Constructor[] getConstructors();
//根据指定参数获得public和非public的构造器
Constructor getDeclaredConstructor(Class[] params);
//获得public的所有构造器
Constructor[] getDeclaredConstructors();

看这些方法如何使用,先来个Student类供我们反射使用

public class Student {

    private static String TAG = Student.class.getSimpleName();
public int age;
private String name; public Student() {
age = 20;
name = "小明";
} public Student(int age, String name) {
Log.e(TAG, "Student: " + "age " + age + " name " + name);
} public void StudentA() {
Log.e(TAG, "StudentA: ");
} public void StudentA(int age) {
Log.e(TAG, "StudentA: " + "age " + age);
} public void StudentA(int age, String name) {
Log.e(TAG, "StudentA: " + "age " + age + " name " + name);
}
}

利用反射分析类的能力

在java.lang.reflect包(反射库)中有三各类Field,MethodConstructor分别用于描述类的域,方法和构造器。这三个类都有一个叫做getName()的方法,用于返回项目的名称。Filed类有一个getType()方法,用于返回描述域所属类型的Class对象。Method和Constructor类有能够报告参数类型的方法,Method类还有一个可以报告返回类型的方法。

这三个类还有一个叫做getModifiers()的方法,它将返回一个整型数值,用不同的位开关描述public和static这样的修饰符使用情况。另外,还可以利用java.lang.reflect包中的Modifier类的静态方法分析getModifiers()返回的整型数值。例如,可以使用Modifier类中的isPublic()isPrivate()isFinal()判断方法或构造器是否是public,private或final。我们需要做的全部工作就是调用Modifier类的相应方法,并对返回的整数数值进行分析,另外,还可以利用Modifier.toString()方法将修饰符打印出来。

Class类中的getFields()getMethods()getConstructors()方法将分别返回类提供的public域、方法和构造器数组,其中包括超类的公有成员。Class类的getDeclareFieds()getDeclareMethods()getDeclareConstructors()方法将分别返回类中声明的全部域、方法和构造器,其中包括私有和受保护成员,但不包括超类的成员。

下面我们来编写一个程序可以做到输入类名,然后打印出这个类的全部信息的作用:

package com.reflect.test;

import com.sun.org.apache.xpath.internal.operations.Mod;

import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Scanner; 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("请输入类名:");
name = in.next();
} try{
Class c1 = Class.forName(name);
Class superclass = c1.getSuperclass();
String modifiers = Modifier.toString(c1.getModifiers());
if(modifiers.length() > 0){
System.out.println(modifiers + " ");
}
System.out.println("class"+name);
if(superclass != null && superclass != Object.class){
System.out.println("extends"+superclass.getName());
}
System.out.println("\n{\n");
printConstructors(c1);
System.out.println();
printMethods(c1);
System.out.println();
printFields(c1);
System.out.println("}");
}catch (ClassNotFoundException e){
e.printStackTrace();
}
System.exit(0);
} private static void printFields(Class c1) {
Field[] fields = c1.getDeclaredFields(); for(Field field : fields){
Class type = field.getType();
String name = field.getName();
System.out.println(" ");
String modifiers = Modifier.toString(field.getModifiers());
if(modifiers.length() > 0){
System.out.println(modifiers + " ");
}
System.out.println(type.getName() + " " + name + ";");
}
} private static void printMethods(Class c1) {
Method[] methods = c1.getDeclaredMethods(); for(Method method : methods){
Class returnType = method.getReturnType();
String name = method.getName();
System.out.println(" ");
String modifiers = Modifier.toString(method.getModifiers());
if(modifiers.length() > 0){
System.out.println(modifiers + " ");
}
System.out.println(returnType.getName()+" "+name+"(");
Class[] paramTypes = method.getParameterTypes();
for(int j = 0; j < paramTypes.length; j++){
if(j > 0){
System.out.println(",");
}
System.out.println(paramTypes[j].getName());
}
System.out.println(");");
}
} private static void printConstructors(Class c1) {
Constructor[] constructors = c1.getDeclaredConstructors();
for(Constructor constructor : constructors){
String name = constructor.getName();
System.out.println(" ");
String modifiers = Modifier.toString(constructor.getModifiers());
if(modifiers.length() > 0){
System.out.println(modifiers + " ");
}
System.out.println(name + "(");
Class[] paramTypes = constructor.getParameterTypes();
for(int j = 0; j < paramTypes.length; j++){
if(j > 0){
System.out.println(",");
}
System.out.println(paramTypes[j].getName()); }
System.out.println(");");
}
}
}

输入java.long.Double

回显:

请输入类名:
java.lang.Double
public final
Disconnected from the target VM, address: '127.0.0.1:51190', transport: 'socket'
classjava.lang.Double
extendsjava.lang.Number { public
java.lang.Double(
double
); public
java.lang.Double(
java.lang.String
); public
boolean equals(
java.lang.Object
); public static
java.lang.String toString(
double
); public
java.lang.String toString(
); public
int hashCode(
); public static
int hashCode(
double
); public static
double min(
double
,
double
); public static
double max(
double
,
double
); public static native
long doubleToRawLongBits(
double
); public static
long doubleToLongBits(
double
); public static native
double longBitsToDouble(
long
); public volatile
int compareTo(
java.lang.Object
); public
int compareTo(
java.lang.Double
); public
byte byteValue(
); public
short shortValue(
); public
int intValue(
); public
long longValue(
); public
float floatValue(
); public
double doubleValue(
); public static
java.lang.Double valueOf(
java.lang.String
); public static
java.lang.Double valueOf(
double
); public static
java.lang.String toHexString(
double
); public static
int compare(
double
,
double
); public static
boolean isNaN(
double
); public
boolean isNaN(
); public static
boolean isFinite(
double
); public static
boolean isInfinite(
double
); public
boolean isInfinite(
); public static
double sum(
double
,
double
); public static
double parseDouble(
java.lang.String
); public static final
double POSITIVE_INFINITY; public static final
double NEGATIVE_INFINITY; public static final
double NaN; public static final
double MAX_VALUE; public static final
double MIN_NORMAL; public static final
double MIN_VALUE; public static final
int MAX_EXPONENT; public static final
int MIN_EXPONENT; public static final
int SIZE; public static final
int BYTES; public static final
java.lang.Class TYPE; private final
double value; private static final
long serialVersionUID;
} Process finished with exit code 0

Java复习总结——详细理解Java反射机制

不积跬步无以至千里

思维导图

Java复习总结——详细理解Java反射机制

扩展阅读:

https://blog.csdn.net/zhangqiluGrubby/article/details/60874013

https://www.daidingkang.cc/2017/07/18/java-reflection-annotations/

https://www.javazhiyin.com/17014.html

https://www.javazhiyin.com/17008.html

Java复习总结——详细理解Java反射机制的更多相关文章

  1. Java基础 -- 深入理解Java类型信息&lpar;Class对象&rpar;与反射机制

    一 RTTI概念 认识Claa对象之前,先来了解一个概念,RTTI(Run-Time Type Identification)运行时类型识别,对于这个词一直是 C++ 中的概念,至于Java中出现RT ...

  2. 【Java】「深入理解Java虚拟机」学习笔记(1) - Java语言发展趋势

    0.前言 从这篇随笔开始记录Java虚拟机的内容,以前只是对Java的应用,聚焦的是业务,了解的只是语言层面,现在想深入学习一下. 对JVM的学习肯定不是看一遍书就能掌握的,在今后的学习和实践中如果有 ...

  3. Java提高篇之理解java的三大特性——继承

    在<Think in java>中有这样一句话:复用代码是Java众多引人注目的功能之一.但要想成为极具革命性的语言,仅仅能够复制代码并对加以改变是不够的,它还必须能够做更多的事情.在这句 ...

  4. 【转】java提高篇&lpar;二&rpar;-----理解java的三大特性之继承

    [转]java提高篇(二)-----理解java的三大特性之继承 原文地址:http://www.cnblogs.com/chenssy/p/3354884.html 在<Think in ja ...

  5. Java语法基础学习DayNineteen(反射机制)

    一.Refection定义 1.概述 Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性 ...

  6. Android(java)学习笔记106-2:反射机制

    1.反射机制: JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为 ...

  7. Android(java)学习笔记46:反射机制

    1. 反射机制: JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称 ...

  8. Java语法基础学习DayTwenty(反射机制续)

    一.Java动态代理 1.代理设计模式的原理 使用一个代理将对象包装起来, 然后用该代理对象取代原始对象. 任何对原始对象的调用都要通过代理. 代理对象决定是否以及何时将方法调用转到原始对象上. 2. ...

  9. Java 干货之深入理解Java泛型

    一般的类和方法,只能使用具体的类型,要么是基本类型,要么是自定义的类.如果要编写可以应用多中类型的代码,这种刻板的限制对代码得束缚会就会很大. ---<Thinking in Java> ...

随机推荐

  1. 十天冲刺---Day7

    站立式会议 站立式会议内容总结: 燃尽图 照片 两个人编码其实效率挺高的.但是在一些方面,比如说页面UI的编写,会非常吃力,很难达到自己的效果. 由于埋头在编码,所以issues的增加随之停止. 有点 ...

  2. S5PV210之beep-bus模型 linux3&period;0&period;8驱动

    目录: 一. bus-driver-device模型 二. 运行结果,及错误解决 三. 怎样利用以有的driver device驱动来写自已的beep-driver-device 驱动       四 ...

  3. Leetcode&num;57 Insert Interval

    原题地址 遍历每个区间intervals[i]: 如果intervals[i]在newInterval的左边,且没有交集,把intervals[i]插入result 如果intervals[i]在ne ...

  4. 2013 Multi-University Training Contest 1 Cards

    数据不是很大,直接枚举约数,判断4个条件是否满足! 这样就得到4种卡片,总共2^4种情况,枚举各种情况即可!!! #include<iostream> #include<cmath& ...

  5. 使用 logback &plus; slf4j 进行日志记录

    此处主要介绍maven web工程下如何使用 logback + slf4j  进行日志记录. logback主要包含三个组成部分:Loggers(日志记录器).Appenders(输出目的在).La ...

  6. sql分页查询公式

    分页查询公式: select top PageRow(每页显示的数据行数) from 表名 where 主键  not in(select top PageRow*(当前页数-1) 主键  from ...

  7. android TextView 之探究

    1:插入图片替换 //代码 mSubjectDetailView = (TextView) findViewById(R.id.subject_detail); CharSequence text = ...

  8. &lbrack;Python Web&rsqb;部署完网站需要做的基本后续工作

    简述 今天自己上线了一个简单的 Page,没有什么功能就是一个展示页. 但是,我发现部署完,上线后,还要弄不少东西.下面就是我记录.整理的一些上线网站基本都会用到的网站和配置. 加入统计代码 这个是必 ...

  9. Docker系列之Docker容器&lpar;读书笔记&rpar;

    一.介绍 容器是独立运行的一个或一组应用,以及它们的运行态环境.对应的,虚拟机可以理解为模拟运行的一整套操作系统和排在上面的应用. 二.容器 2.1 启动容器 启动容器有两种方式,一种是基于镜像新建一 ...

  10. JS使用onscroll、scrollTop实现图片懒加载

    今天做到项目中的图片展示,由于每一页的图片数量都很多,因此需要为图片的展示设计一种懒加载的功能. 第一要做的当然就是给程序添加滚动监听事件. //触发拉取图片开关,保证正在拉取时不能再次触发 var ...