@

1 Class 类是什么?

在 Java 中, 一切皆对象。

比如

class Foo{

}

这个类本身就是 java.liang.Class 的一个对象。 每一个 .class 文件在类加载器加载了之后, 都会在 JVM 中创建一个 Class 对象。

所有的类都是在第一次使用时, 动态加载到 JVM 中。 当程序创建第一个对类的静态成员函数(构造函数也是静态方法)的引用时, 就会加载这个类。 一旦某个类的 Class 对象被载入内存中, 它就会从来创建这个类的所有对象。

所有反射的入口都是 java.liang.Class。 因为 Java 中规定了 java.lang.reflect 包下的所有类的构造函数都不为 public, 因此, 需要获得这些类的对象都需要调用 Class 类中适当的的方法。

2 如何获取 Class 对象

Class 对象由 JVM 自动创建, 我们可以通过以下几种方法获取相应类或接口的该对象实例。

2.1 Object.getClass()

我们都知道所有的类都是继承于 Object, 因此, Object 中的方法, 任何类都可以使用。

    public final native Class<?> getClass();

该方法时 final 所修饰的, 不能重写。

举个例子

    @Test
public void testClass() {
Class clazz = "foo".getClass();
System.out.println(clazz.toString());
}

该例子中, "foo" 是 String 类型的实例, 因此, 其调用 getClass() 所返回的类型就是 String。

结果

class java.lang.String

2.2 .class 语法

如果我们想要获取某个类的 Class, 我们又没有相应的实例, 那么通过 .class 也可以获取该类的 Class 对象。 基本数据类型通过该方法是最容易获取到其 Class 对象 的。

    @Test
public void testDotClass() {
boolean b = false;
// Class clazz = b.getClass(); // 编译错误
Class clazz = boolean.class;
System.out.println(clazz); Boolean bw = false;
System.out.println(bw.getClass()); System.out.println(HashMap.class);
}

输出

boolean
class java.lang.Boolean
class java.util.HashMap

2.3 Class.forName()

如果我们知道某个类的全限定名, 我们可以通过该方法获得对应的 Class 对象。 该方法不能对基本类型使用。

使用起来很简单

    @Test
public void testFullNameClass() {
try {
Class clazz = Class.forName("java.lang.System");
System.out.println(clazz);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}

结果

class java.lang.System

该方法可能会找不到对应的类, 需要处理受检异常 ClassNotFoundException。 框架用的大多都是该方法, 因为前面两种需要知道类的实例或类的类名, 而第三中需要的是类的全限定名, 是一串字符串, 我们可以通过配置或扫描等方式告知框架。

2.4 通过包装类的 TYPE 成员

对于基本数据类型, 除了以上的 .class 方法之外, 我们还可以使用其对对应包装类的 TYPE 成员变量来获取 Class 对象。

System.out.println(Double.TYPE); // 输出 double

3 Class 的主要方法及其示例

Class 里面存储了对应类的所有信息, 因此, 我们可以获得类相关的信息。

一个类的组成

  • 属性:对象数据的描述
  • 构造方法:用于实例化对象
  • 普通方法:对象的行为
  • 注解
  • 内部类:在类中声明的类(inner class)
  • 块:分静态块与实例块
  • 类的声明:(访问权限修饰符public.default(可忽略不写,为默认))(修饰符final.abstract.synchronized)class 类名{ 类体 }

3.1 属性相关

获取全部 public 属性, 包括其父类, 接口的

 public Field[] getFields();

获取指定的名称的属性

 public Field getField(String name);

获取所有本类(不包含父类, 接口)声明的属性

 public Field[] getDeclaredFields();

获取本类(不包含父类, 接口)指定的名称的声明属性

public Field getDeclaredField(String name);

3.2 构造函数相关

获取所有的 public 构造器

public Constructor<?>[] getConstructors()

获取指定参数的 public 构造器

public Constructor<?> getConstructor(Class<?>... parameterTypes)

获取声明(public, private, protected, friendly)的所有构造器

public Constructor<?>[] getDeclaredConstructors()

获取声明(public, private, protected, friendly)的指定参数构造器

public Constructor<?> getDeclaredConstructor(Class<?>... parameterTypes)

3.3 普通方法相关

获取所有的 public 方法,包括其父类, 接口的

public Method[] getMethods();

获取指定参数的 public 方法, 包括其父类, 接口的

public Method getMethod(String name, Class<?>... parameterTypes);

获取声明(public, private, protected, friendly)的所有普通方法

public Method[] getDeclaredMethods();

获取声明(public, private, protected, friendly)的指定参数的普通方法

public Method getDeclaredMethod(String name, Class<?>... parameterTypes);

3.4 注解相关

判断是否为注解, 如果是注解, 就一定是接口

 public boolean isAnnotation()

判断类上面有没有指定类型的注解(包括继承的)

 public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass)

获取类上面的所有注解(包括继承的), 没有注解返回长度 0 的数组

public Annotation[] getAnnotations();

获取类上存在的、指定类型的注解(包括继承的),如果该类型注解不存在,则返回null

public <A extends Annotation> A getAnnotation(Class<A> annotationClass);

获取类上面的指定类型的注解(包括继承的), 没有注解返回长度为 0 的数组

public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationClass);

获取类上面指定类型的注解(不包括继承的注解), 没有则返回 null

public <A extends Annotation> A getDeclaredAnnotation(Class<A> annotationClass)

获取类上面所有的注解(不包括继承的注解), 没有则返回长度为0的数组

public Annotation[] getDeclaredAnnotations()

获取类上面指定类型的注解(不包括继承的注解), 没有注解返回长度为 0 的数组

public <A extends Annotation> A[] getDeclaredAnnotationsByType(Class<A> annotationClass)

3.5 其他常用的方法

返回 Class 对象表示的类型(类、接口、数组或基本类型)的完整路径名字符串

public String getName()

可以通过该方法创建对象, 需要有默认构造函数

public T newInstance()

获取该类的类加载器

public ClassLoader getClassLoader()

返回该Class对象对应类所实现的全部接口

public Class<?>[] getInterfaces()

返回此Class对象对应类的超类的Class对象

public Class<? super T> getSuperclass()

判断此class对象是否表示一个数组类

public boolean isArray()

判定指定的 Class 对象是否表示一个接口类型

public boolean isInterface()

判定指定的 Class 对象是否表示一个 Java 的基本类型

public boolean isPrimitive()

判断此class对象是否表示一个枚举

oolean isEnum()

判断obj是否是此class对象的实例,该方法可以完全代替instanceof操作符

boolean isInstance(Object obj)

判断是否为匿名类

public boolean isAnonymousClass()

获取所有的内部类

public Class<?>[] getDeclaredClasses()

获取其所在的外部类

public Class<?> getDeclaringClass()

反射那些基础-Class的更多相关文章

  1. java Reflection(反射)基础知识讲解

    原文链接:小ben马的java Reflection(反射)基础知识讲解 1.获取Class对象的方式 1.1)使用 "Class#forName" public static C ...

  2. java反射机制(基础版)

    package com.reflect; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import ja ...

  3. C#反射之基础应用

    今天把反射的东西整理了一下 , 提供了最全面的东西 , 当然也是基础的东西 ,在学好了这一切的基础上 , 大家可以学习反射的具体插件等应用 首先我们建立一个类库 , 将它生成为 reflectPrj  ...

  4. JAVA反射机制基础概念

    反射机制:所谓的反射机制就是java语言在运行时拥有一项自观的能力.通过这种能力可以彻底的了解自身的情况为下一步的动作做准备.下面具体介绍一下java的反射机制.这里你将颠覆原来对java的理解. J ...

  5. java反射的基础学习代码

    java反射的学习,好多东西不太理解,主要分析了constructor,method,field,数组和调用main函数等反射的多个方面小例子. 主要的练习类 package javaAdvanced ...

  6. 透彻分析反射的基础_Class类

    一.反射的基石--->Class类 1. Java类用于描述一类事物的特性,该类事物有什么属性,没有什么属性,值域这个属性的值是什么,则是由这个类的实例对象来确定的,不同的实例对象有不同的属性值 ...

  7. C# 反射_基础

    反射用于在程序运行过程中,获取类里面的信息或发现程序集并运行的一个过程.通过反射可以获得.dll和.exe后缀的程序集里面的信息.使用反射可以看到一个程序集内部的类,接口,字段,属性,方法,特性等信息 ...

  8. Java基础---基础加强---增强for循环、自动拆装箱及享元、枚举的作用、实现带有构造方法、透彻分析反射的基础_Class类、成员变量的反射、数组参数的成员方法进行反射、数组的反射应用

    在perference 加content Assist 可以设置快捷键 透视图与视图 透视图:Debug和java主窗口 视图:每一个小窗口就是视图 高版本的java可运行低版本的java版本 常见的 ...

  9. Java反射之基础概念

    0.实例准备 package com.blueStarWei.invoke; public class Student { private String name; public Student() ...

随机推荐

  1. Testlink1.9.17使用方法(第七章 测试用例集管理)

    第七章 测试用例集管理 QQ交流群:585499566 测试用例准备好以后,可以对测试用例集进行相关的操作. 一. 添加测试用例到测试计划中 在主页的“当前测试计划”下拉列表里-->选择一个测试 ...

  2. leetcode-973最接近原点的K个点

    leetcode-973最接近原点的K个点 题意 我们有一个由平面上的点组成的列表 points.需要从中找出 K 个距离原点 (0, 0) 最近的点. (这里,平面上两点之间的距离是欧几里德距离.) ...

  3. ELk(Elasticsearch, Logstash, Kibana)的安装配置

    目录 ELk(Elasticsearch, Logstash, Kibana)的安装配置 1. Elasticsearch的安装-官网 2. Kibana的安装配置-官网 3. Logstash的安装 ...

  4. shell编程—注释、字符串和数组(四)

    shell注释 以#作为注释符号 shell中没有多行注释,只能一行加一个#号 字符串操作 1.拼接字符串 2.获取字符串长度 string=“khjf” echo ${#string} 3.提取子字 ...

  5. EF CodeFirst使用Nuget更新数据库

    常用命令: 1.开启迁移 Enable-Migrations -EnableAutomaticMigrations 2.添加一条迁移记录 Add-Migration AddMigration001 3 ...

  6. c/c++ 线性表之单向循环链表

    c/c++ 线性表之单向循环链表 线性表之单向循环链表 不是存放在连续的内存空间,链表中的每个节点的next都指向下一个节点,最后一个节点的下一个节点不是NULL,而是头节点.因为头尾相连,所以叫单向 ...

  7. Xlua 不同平台链接库编译

    xlua 下载包中提供lua5.3的库文件,如果需要luajit或者自己添加删除的就需要自己进行编译. Lua53版本没那么多事,主要是LuaJIt版本折腾的比较久. 工具 Xlua使用CMake进行 ...

  8. 【工匠大道】升级Mac下的svn,解决命令行不能使用svn的问题

    本文地址 原文地址 一. 为什么要升级SVN? 因为MAC上默认安装的是1.6版本,在使用时经常会提示SVN版本太旧,所以一定要升级 二. 怎么升级? 所有软件安装都是这三步吧,哈哈 第一步: 下载 ...

  9. 13.scrapy框架的日志等级和请求传参

    今日概要 日志等级 请求传参 如何提高scrapy的爬取效率 今日详情 一.Scrapy的日志等级 - 在使用scrapy crawl spiderFileName运行程序时,在终端里打印输出的就是s ...

  10. (转)Spring Boot 2 (六):使用 Docker 部署 Spring Boot 开源软件云收藏

    http://www.ityouknow.com/springboot/2018/04/02/docker-favorites.html 云收藏项目已经开源2年多了,作为当初刚开始学习 Spring ...