对于每一种类,Java虚拟机都会初始化一个Class类型的实例,当我们编译一个新的类就会产生一个Class对象,并且这个Class对象会被保存在同名的.class文件里。当我们new一个对象的时候,或者引用静态变量时,Java虚拟机的类加载器系统会将对应的Class对象加载到JVM中,然后JVM再根据这个Class相关的信息创建我们需要的实例对象或者提供静态变量的引用值。

获取class对象及部分信息的方法:

@Overrideprotected void initView() {//获取class类的几种方式Log.i(TAG,"1 通过对象实例获取class==============================");Class stringClass = "abc".getClass();Log.i(TAG,"普通对象的class:" + stringClass);Log.i(TAG,"2 通过类的类型获取class==============================");Class easyTypeClass = int.class;Log.i(TAG,"基本类型的class:" + easyTypeClass);Class enumClass = E.A.getClass();Log.i(TAG,"enum类型的class:" + enumClass);Log.i(TAG,"3 通过类的全局限定名获取class==============================");try {Class nameClass = Class.forName("java.lang.String");Log.i(TAG,"通过全局限定名 java.lang.String 获取class: " + nameClass);Class cDoubleArrayClass = Class.forName("[D");Log.i(TAG,"通过全局限定名 [D 获取double[].class:" + cDoubleArrayClass);Class cStringArrayClass = Class.forName("[[Ljava.lang.String;");Log.i(TAG,"通过全局限定名 [[Ljava.lang.String; 获取String[][].class: " + cStringArrayClass);Log.i(TAG,"4 通过包装类的TYPE字段获取class==============================");Class doubleClass = Double.TYPE;Log.i(TAG,"基本类型的包装类也可以通过 TYPE字段获取Class:" + doubleClass);Log.i(TAG,"5 获取指定类的父类 class==============================");Class baseFraClass = BaseFragment.class;Log.i(TAG,"BaseFragment的Class对象: " + baseFraClass);Class baseFraFatherClass = baseFraClass.getSuperclass();Log.i(TAG,"BaseFragment的父类的Class对象: " + baseFraFatherClass);Log.i(TAG,"获取类的详细信息, 修饰符,类名,泛型类型,父类, 以hashMap类为例====================");Class hashMapClass = HashMap.class;Log.i(TAG,"hashMap 的 name为:" + hashMapClass.getName());Log.i(TAG,"hashMap 的 SimpleName为:" + hashMapClass.getSimpleName());Log.i(TAG,"hashMap 的 类修饰符为:" + Modifier.toString(hashMapClass.getModifiers()));TypeVariable[] tv = hashMapClass.getTypeParameters();StringBuilder pas = new StringBuilder();for (int i = 0; i < tv.length; i++) {TypeVariable t = tv[i];pas.append(t.getName() + "  ");}Log.i(TAG,"hashMap 的 泛型为:" + pas);Type[] ts = hashMapClass.getGenericInterfaces();StringBuilder genericInterface = new StringBuilder();for (int i = 0; i < ts.length; i++) {genericInterface.append(ts[i].toString() + "  ");}Log.i(TAG,"hashMap 的 实现接口, getGenericInterfaces :" + genericInterface);Type[] tss = hashMapClass.getInterfaces();StringBuilder interfaces = new StringBuilder();for (int i = 0; i < tss.length; i++) {interfaces.append(tss[i].toString() + "  ");}Log.i(TAG,"hashMap 的 实现接口, getInterfaces :" + interfaces);List<Class> fathers = new ArrayList<>();addAncestor(ReflexDemoAct.class, fathers);StringBuilder builder = new StringBuilder();for (int i = 0; i < fathers.size(); i++) {Class c = fathers.get(i);builder.append(c.getCanonicalName() + "\n");}Log.i(TAG, "ReflexDemoAct 的继承树为 : \n" + builder.toString());Annotation[] annotations = ReflexDemoAct.class.getAnnotations();StringBuilder annotationString = new StringBuilder();if(null == annotations || annotations.length == 0){Log.i(TAG, "ReflectDemoAct类没有注解");} else {for (int i = 0; i < annotations.length; i++) {Annotation annotation = annotations[i];annotationString.append(annotation.toString() + "   ");}Log.i(TAG, "ReflectDemoAct类的Runtime类型的注解是: "+ annotationString.toString());}//以下是变量,方法,构造方法对应的类对应Log.i(TAG, Field.class.getCanonicalName() + ", 对应类的变量");Log.i(TAG, Method.class.getCanonicalName() + ", 对应类的方法");Log.i(TAG, Constructor.class.getCanonicalName() + ", 对应类的构造方法");Log.i(TAG, "但是,上面的方法正常情况下都不能获取private修饰的变量");Log.i(TAG, AccessibleObject.class.getCanonicalName() + ", 通过它的setAccessible()方法来取消Java语言访问权限的检查");Log.i(TAG, "很庆幸的是,Field, Method, Constructor方法均继承自AccessibleObject类,均可以设置这个入口,这样就可以访问private的内容了");Class reflexActClass = ReflexDemoAct.class;Field[] fields = reflexActClass.getFields();StringBuilder fieldBuild = new StringBuilder();for (int i = 0; i < fields.length; i++) {fieldBuild.append(fields[i].toString() + "\n");}Log.i(TAG, "得到的成员变量为: " + fieldBuild.toString());} catch (ClassNotFoundException e) {e.printStackTrace();}}
private void addAncestor(Class<?> cla, List<Class> claList){Class<?> fatherCla = cla.getSuperclass();if (null != fatherCla){claList.add(fatherCla);addAncestor(fatherCla, claList);}}

Field

通过Field可以访问给定对象的类变量,仅对于当前类,不包含其父类里面的变量,包括获取变量的类型,修饰符,注解,变量的名,变量的值,或者重新设置变量值。即使变量是private的。Class类有4种获取Field的方式。

  • getDeclaredField(String name) 获取指定的变量(只要是声明的变量都能获得,即使是private的。)
  • getField(String name), 获取指定的变量(但是只能是public的)
  • deDeclaredFields(), 获取所有声明的变量,(包括private的)
  • getFields(),获取所有的public变量。
package com.example.forev.mycodelibrary;
import android.util.Log;
public class Cat {public static final String TAG = Cat.class.getSimpleName();private String name;@Deprecatedpublic int age;public Cat(String name, int age){this.name = name;this.age = age;}public String getName(){return name;}public void eat(String food){Log.d(TAG, "eat food " + food);}public void eat(String... foods){StringBuilder s = new StringBuilder();for(String food : foods){s.append(food);s.append(" ");}Log.d(TAG, "eat food " + s.toString());}public void sleep(){Log.d(TAG, "sleep");}@Overridepublic String toString() {return "name = " + name + " age = " + age;}
}
private void logFieldUses() {Class reflexActClass = Cat.class;Field[] fields = reflexActClass.getDeclaredFields();StringBuilder fieldBuild = new StringBuilder();fieldBuild.append("\n");for (int i = 0; i < fields.length; i++) {Field f = fields[i];fieldBuild.append("变量名:" + f.getName() + " ");fieldBuild.append("类型:" + f.getType() + " ");fieldBuild.append("修饰符:"+ Modifier.toString(f.getModifiers()) + " ");Annotation[] as = f.getAnnotations();if (null == as || as.length == 0){fieldBuild.append("没有注解\n");} else {for (int k = 0; k < as.length; k++) {Annotation an = as[k];fieldBuild.append("注解" + k + ":" + an.toString() + " ");}}fieldBuild.append("\n");}Log.i(TAG, "通过 getFields() 得到的public成员变量为: " + fieldBuild.toString());try {Cat cat = new Cat("yayali", 3);Field name = reflexActClass.getDeclaredField("name");//name是private类型的,所以要设置一下才可以访问。name.setAccessible(true);String nameValue = (String) name.get(cat);Log.i(TAG, "name的值为:" + nameValue);Field age = reflexActClass.getField("age");int ageValue = (int) age.get(cat);Log.i(TAG, "age的值为:" + ageValue);Field tag = reflexActClass.getField("TAG");String tagValue = (String) tag.get(cat);Log.i(TAG, "TAG的值为:" + tagValue);} catch (NoSuchFieldException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}

打印结果为:

2019-03-06 15:32:26.001 7835-7835/com.example.forev.mycodelibrary I/ReflexDemoAct: 通过 getFields() 得到的public成员变量为: 变量名:age 类型:int 修饰符:public 注解0:@java.lang.Deprecated() 变量名:name 类型:class java.lang.String 修饰符:private 没有注解变量名:TAG 类型:class java.lang.String 修饰符:public static final 没有注解
2019-03-06 15:32:26.001 7835-7835/com.example.forev.mycodelibrary I/ReflexDemoAct: name的值为:yayali
2019-03-06 15:32:26.001 7835-7835/com.example.forev.mycodelibrary I/ReflexDemoAct: age的值为:3
2019-03-06 15:32:26.001 7835-7835/com.example.forev.mycodelibrary I/ReflexDemoAct: TAG的值为:Cat

Method

代码如下:

private void logMethodUses(){Class catClass = Cat.class;Method[] methods = catClass.getDeclaredMethods();StringBuilder builder = new StringBuilder();builder.append("\n");for (int i = 0; i < methods.length; i++) {Method method = methods[i];builder.append("方法名为:" + method.getName() + " ");builder.append("修饰符为:" + Modifier.toString(method.getModifiers()) + " ");builder.append("返回类型为:" + method.getGenericReturnType().toString() + " ");//方法抛出的异常Type[] exceptionTypes = method.getGenericExceptionTypes();if (0 == exceptionTypes.length){builder.append("没有异常! ");} else {builder.append("\"\\n 抛出的异常为:\\n\"");for (int k = 0; k < exceptionTypes.length; k++) {Type type = exceptionTypes[k];builder.append(type.toString() + "\n");}}//方法的参数,包括类型,名称,Type[] ptypes = method.getGenericParameterTypes();if (0 == ptypes.length){builder.append("没有参数! ");} else {builder.append("参数类型为:\n");for (int c = 0; c < ptypes.length; c++) {Type type = ptypes[c];builder.append(type.toString() + "\n");}}if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {Parameter[] params = method.getParameters();if (0 == params.length) {builder.append(" 没有参数");} else {for(int y = 0; y < params.length; y++) {Parameter parameter = params[y];String pName = parameter.getName();String type = parameter.getType().toString();builder.append(" 参数" + y + "的名字是:" + pName + " 类型是:" + type + "\n");}}}//判断是否是可变参数builder.append(method.isSynthetic() ? "有可变参数! " : "没有可变参数! ");builder.append("\n");}Log.i(TAG, "method相关的信息为: " + builder.toString());Log.i(TAG, "\n 开始通过反射调用方法!");Cat cat = new Cat("huahua", 6);Method method = null;try {//重载机制的存在,我们得传入一个描述具体传什么类型的参数method = Cat.class.getMethod("eat", String.class);method.invoke(cat, "鱼干");} catch (NoSuchMethodException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}}

打印日志:

2019-03-06 18:17:53.848 14929-14929/com.example.forev.mycodelibrary I/ReflexDemoAct: method相关的信息为: 方法名为:eat 修饰符为:public 返回类型为:void 没有异常! 参数类型为:class java.lang.String参数0的名字是:arg0 类型是:class java.lang.String没有可变参数! 方法名为:eat 修饰符为:public transient 返回类型为:void 没有异常! 参数类型为:class [Ljava.lang.String;参数0的名字是:arg0 类型是:class [Ljava.lang.String;没有可变参数! 方法名为:getName 修饰符为:public 返回类型为:class java.lang.String 没有异常! 没有参数!  没有参数没有可变参数! 方法名为:sleep 修饰符为:public 返回类型为:void 没有异常! 没有参数!  没有参数没有可变参数! 方法名为:toString 修饰符为:public 返回类型为:class java.lang.String 没有异常! 没有参数!  没有参数没有可变参数!
2019-03-06 18:17:53.848 14929-14929/com.example.forev.mycodelibrary I/ReflexDemoAct:  开始通过反射调用方法!
2019-03-06 18:17:53.848 14929-14929/com.example.forev.mycodelibrary D/Cat: eat food 鱼干

Constructor 构造器

private void logConstructorUses(){Log.i(TAG, "测试构造方法!");try {Class catClass = Cat.class;Constructor constructor = catClass.getConstructor(String.class, int.class);Cat cat = (Cat) constructor.newInstance("黑猫警长", 12);Method sleepMethod = catClass.getMethod("sleep");sleepMethod.invoke(cat);} catch (NoSuchMethodException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}}

打印日志为:

2019-03-06 18:27:43.162 15201-15201/com.example.forev.mycodelibrary I/ReflexDemoAct: 测试构造方法!
2019-03-06 18:27:43.162 15201-15201/com.example.forev.mycodelibrary D/Cat: sleep

Java Class类的简单用法相关推荐

  1. python简单定义_python定义类的简单用法

    python定义的类使用方法: 使用"obj=类名()"语句将类实例化,然后用"obj.函数名"就可以调用类里面定义的各种函数了 示例如下: 将Bili类实例化 ...

  2. js的对象和java的类的简单区别

    记一个面试题.如题 java是面向对象的,也就是有继承,封装,多态. js是基于对象的,也就是说没有上述三点.js的继承等是通过原型链或其他方法进行实现的,es6的class本质上还是对象,和java ...

  3. Java中console类的简单用法

    Java.io.Console 只能用在标准输入.输出流未被重定向的原始控制台中使用,在 Eclipse 或者其他 IDE 的控制台是用不了的. import java.io.Console; pub ...

  4. Scanner类的简单用法介绍!

    Scanner是Java中的一个新特征,Java程序员可以通过Scanner类来获取用户的输入,帮助程序员接收从键盘输入的数据,对于程序员而言非常有帮助.当程序需要从键盘获取用户输入的命令或数据时,例 ...

  5. Java枚举类——valueOf()的用法

    目录 引言 valueOf()用法 更新 引言 最近学习Java,到了枚举类部分,书上列举了几个方法: int compareTo() String name() int ordinal() Stri ...

  6. java中Scanner的简单用法

    一.用法 1.先导入Java.util.Scanner包 import java.util.Scanner; 2.创建Scanner类的对象 Scanner sc=new Scanner(System ...

  7. html单页面js完成表数据库自动生成带注释的java实体类和简单的增删改查sql

    支持Mysql和Oracle,mybatis和ibatis可选.功能主要还是字符串的拼凑完成的,把用把表信息复制过来或者增加后台,就可以生成简单的增删改查了 临时体验点这里 我也不知道地址什么时候失效 ...

  8. CserialPort类的简单用法

    CserialPort类的用法打开串口:if (m_Comm.InitPort(this,3,115200,'n',8,1,EV_RXCHAR, 512)) //接收数据类型为 //EV_RXCHAR ...

  9. java中Object.equals()简单用法

    /* equals()方法默认的比较两个对象的引用! */ class Child {int num;public Child(int x){num = x;}//人文的抛出运行时异常的好处是:可以自 ...

最新文章

  1. C#精粹,一本都不能少
  2. jQuer or js 插件aptana studio 3.4.0)教你玩转eclipse配置(全世
  3. pandas 按日期范围筛选数据的实现
  4. Django开发—如何重置migration
  5. 云计算基础知识:CPU虚拟化
  6. uva 10061——How many zero\'s and how many digits ?
  7. LinearLayout和RelativeLayout
  8. JS 数字,金额用逗号隔开
  9. R语言基础 训练营公告
  10. j2ee和mysql怎么连接_Eclipse下配置j2ee开发环境及与MySQL数据库的连接
  11. 代理(Proxy)和背靠背用户代理(B2BUA)
  12. HDU 4050 wolf5x 概率dp 难度:1
  13. 在EWF上启用一个Hibernate Once/Resume Many环境
  14. 浪曦_Struts2应用开发系列_第2讲.Struts2的类型转换--出现的问题笔记
  15. fences卸载_Win10系统怎样卸载fences?Win10系统卸载fences图文教程-系统城
  16. ctc5(ctc5160)
  17. 学习 react-native-sqlite-storage 案例
  18. 计算机毕业设计之java+ssm疫情防控志愿者管理系统
  19. Predicting human microbe–disease associations via graph attention networks with inductive matrix论文解析
  20. 【吹爆】2022金三银四高频面试题最强合集

热门文章

  1. 育儿-《让孩子远离焦虑》书中的精髓:家长如何帮助孩子解决他们自身的焦虑问题。
  2. 年度Java技术盘点,懂这些技术的程序员2019年薪资翻倍!
  3. 解决虚拟机中Win7系统无法安装vmware tools问题
  4. Java性能优化怎么做好
  5. 德智体美等方面表现 学生年度评语
  6. suspend(挂起)和resume(继续执行)线程
  7. git学习-如何将本地项目上传(同步)到github远程仓库
  8. DSP6455开发: dsp.lib库使用总结
  9. GLFore便携式声学成像仪G100功能
  10. CAN整车网络学习-01