java基础知识(十一)java反射机制(上)
一、class类
Class类是java语言定义的特定类的实现,在java中每个类都有一个相应的Class对象,以便java程序运行时系统(JVM)对所有对象进行运行时类型标识,即Class对象,JVM可以通过该对象操作相应的类(如选准正确的方法执行)。
Class类用于封装被装入JVM中类(类或接口)的信息(类名、类型属于class、interface、enum还是annotation),是java反射机制的基础,通过Class类我们可以获得关于一个类的相关信息。
在程序运行时,如果需要生成某个对象,这时JVM首先检测这个类的Class对象是否已经加载(关于类 的加载会咋后面讲到),如果没有,JVM就会根据文件名查找.class文件将其载入,用于创建所需要的实例。JVM为每个类管理一个独一无二的Class对象(前提使用了同一个类加载器)。
基本数据类型(boolean、byte、char、short、int、long、float 和 double)和关键字void也对应一个Class对象。另外,每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。
Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的,因此不能显式地声明一个Class对象。
1、获取某个类对应的Class对象的三种方法
要想对JVM中Class对象封装的类信息进行访问,首先的获取对应类的Class对象,我们可以通过以下三种方式实现:
a、通过Object的getClass()方法获取(所有的java对象都具备这个方法)
b、使用.class的方式(使用类名加“.class”的方式即会返回与该类对应的Class对象,不需要创建该类的对象)
c、使用Class.forName()方法,该方法据类名(字符串,包括类所在的包,如com.baidu.User)获取与该类关联的Class对象。
下面是一段代码示例:
- public class ObtainClass {
- public static void main(String[] args) {
- try {
- String str1 = "abc";
- System.out.println("通过Object的getClass()方法获取 : " + str1.getClass());
- System.out.println("使用.class的方式获取 : " + String.class);
- System.out.println("使用Class.forName()方法获取 : " + Class.forName("java.lang.String"));
- System.out.println(str1.getClass() == String.class);
- System.out.println(str1.getClass() == Class.forName("java.lang.String"));
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- }
- }
- }
由上面代码可以看出,每个类都对应唯一的Class对象。
2、Class类的常用方法
- public class ClassTest {
- public static void main(String[] args) {
- try {
- System.out.println("返回与带有给定字符串名的类或接口相关联的 Class 对象 : " + Class.forName("com.classTest.classload.CTest"));
- System.out.println("以 String 的形式返回此 Class 对象所表示的实体(类、接口、数组类、基本类型或 void)名称 : " + Class.forName("com.classTest.classload.CTest").getName());
- System.out.println("获取此类的包 : " + Class.forName("com.classTest.classload.CTest").getPackage());
- System.out.println("使用给定的类加载器,返回与带有给定字符串名的类或接口相关联的 Class 对象 : " + Class.forName("com.classTest.classload.CTest", true, ClassLoader.getSystemClassLoader()));
- System.out.println("返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的超类的 Class : " + Class.forName("com.classTest.classload.CTest").getSuperclass());
- System.out.println("返回源代码中给出的底层类的简称 : " + Class.forName("com.classTest.classload.CTest").getSimpleName());
- System.out.println("获取此类的标记 : " + Class.forName("com.classTest.classload.CTest").getSigners());
- CTest ct = new CTest();
- System.out.println("如果存在该元素的指定类型的注释,则返回这些注释,否则返回 null : " + ct.annotationType());
- System.out.println("返回 Java Language Specification 中所定义的底层类的规范化名称 : " + Class.forName("com.classTest.classload.CTest").getCanonicalName());
- System.out.println("返回一个包含某些 Class 对象的数组,这些对象表示属于此 Class 对象所表示的类的成员的所有公共类和接口 : " + Class.forName("com.classTest.classload.CTest").getClasses());
- System.out.println("返回该类的类加载器 : " + Class.forName("com.classTest.classload.CTest").getClassLoader());
- System.out.println("返回表示数组组件类型的 Class : " + Class.forName("com.classTest.classload.CTest").getComponentType());
- System.out.println("返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法 : " + Class.forName("com.classTest.classload.CTest"));
- System.out.println("返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法 : " + Class.forName("com.classTest.classload.CTest").getConstructors().length);
- System.out.println("返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段 : " + Class.forName("com.classTest.classload.CTest").getDeclaredField("age").getName());
- System.out.println("返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段 : " + Class.forName("com.classTest.classload.CTest").getDeclaredFields().length);
- System.out.println("返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段 : " + Class.forName("com.classTest.classload.CTest").getField("str"));
- System.out.println("返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表示的类或接口的所有可访问公共字段 : " + Class.forName("com.classTest.classload.CTest").getFields().length);
- System.out.println("返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法 : " + Class.forName("com.classTest.classload.CTest").getDeclaredMethod("annotationType").getName());
- System.out.println("返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法 : " + Class.forName("com.classTest.classload.CTest").getDeclaredMethods().length);
- System.out.println("如果此 Class 对象表示某一方法中的一个本地或匿名类,则返回 Method 对象,它表示底层类的立即封闭方法 : " + Class.forName("com.classTest.classload.CTest").getEnclosingMethod());
- System.out.println("返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法 : " + Class.forName("com.classTest.classload.CTest").getMethod("annotationType"));
- System.out.println("返回一个包含某些 Method 对象的数组,这些对象反映此 Class 对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共 member 方法 : " + Class.forName("com.classTest.classload.CTest").getMethods().length);
- System.out.println("返回此类或接口以整数编码的 Java 语言修饰符 : " + Class.forName("com.classTest.classload.CTest").getModifiers());
- System.out.println("如果此 Class 对象表示一个注释类型则返回 true : " + Class.forName("com.classTest.classload.ETest").isAnnotation());
- System.out.println("当且仅当底层类是匿名类时返回 true : " + Class.forName("com.classTest.classload.ETest").isAnonymousClass());
- System.out.println("判定此 Class 对象是否表示一个数组类 : " + Class.forName("com.classTest.classload.ETest").isArray());
- System.out.println("判定此 Class 对象所表示的类或接口与指定的 Class 参数所表示的类或接口是否相同,或是否是其超类或超接口 : " + Class.forName("com.classTest.classload.ETest").isAssignableFrom(Class.forName("com.classTest.classload.ETest")));
- System.out.println("当且仅当该类声明为源代码中的枚举时返回 true : " + Class.forName("com.classTest.classload.ETest").isEnum());
- System.out.println("判定指定的 Object 是否与此 Class 所表示的对象赋值兼容 : " + Class.forName("com.classTest.classload.CTest").isInstance(Class.forName("com.classTest.classload.CTest").newInstance()));
- System.out.println("判定指定的 Class 对象是否表示一个接口类型 : " + Class.forName("com.classTest.classload.CTest").isInterface());
- System.out.println("当且仅当底层类是本地类时返回 true : " + Class.forName("com.classTest.classload.CTest").isLocalClass());
- System.out.println("当且仅当底层类是成员类时返回 true : " + Class.forName("com.classTest.classload.CTest").isMemberClass());
- System.out.println("判定指定的 Class 对象是否表示一个基本类型 : " + Class.forName("com.classTest.classload.CTest").isPrimitive());
- System.out.println("如果此类是复合类,则返回 true,否则 false : " + Class.forName("com.classTest.classload.CTest").isSynthetic());
- System.out.println("创建此 Class 对象所表示的类的一个新实例 : " + Class.forName("com.classTest.classload.CTest").newInstance().toString());
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- } catch (NoSuchFieldException e) {
- e.printStackTrace();
- } catch (NoSuchMethodException e) {
- e.printStackTrace();
- } catch (InstantiationException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- }
- }
- }
- class CTest implements Annotation{
- private int age;
- private String name;
- public String str;
- public Class<? extends Annotation> annotationType() {
- return CTest.class;
- }
- @Override
- public String toString() {
- return "CTest{" +
- "age=" + age +
- ", name='" + name + '\'' +
- ", str='" + str + '\'' +
- '}';
- }
- }
- enum ETest{
- CN,
- EN
- }
二、Method类
Method
提供关于类或接口上单独某个方法(以及如何访问该方法)的信息。所反映的方法可能是类方法或实例方法(包括抽象方法)。
- public class MethodTest {
- public static void main(String[] args) throws Exception {
- Class clazz = Class.forName("com.classTest.classload.MT");
- Method[] m = clazz.getMethods();
- for (Method mh : m) {
- System.out.print(mh.getName() + " | " + mh.getDefaultValue() + " | " + mh.getReturnType());
- Class[] c = mh.getParameterTypes();
- System.out.print(" | len = " + c.length + " | ");
- for (Class tv : c) {
- System.out.print(" " + tv.getName());
- }
- System.out.println();
- }
- Method method = clazz.getMethod("mt", String.class);
- method.invoke(clazz.newInstance(), "test method");// 对带有指定参数的指定对象调用由此 Method 对象表示的底层方法
- }
- }
- class MT {
- public String mt(String str) {
- System.out.println(str);
- return str;
- }
- }
三、Field类
Field
提供有关类或接口的单个字段的信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)字段或实例字段。
- public class FieldTest {
- public static void main(String[] args) throws Exception {
- Class clazz = Class.forName("com.classTest.classload.FT");
- Field[] f = clazz.getFields();
- for(Field fd : f) {
- System.out.println(fd.getName() + " | " + fd.getType() + " | " + fd.getModifiers() + " | " + fd.get(""));
- }
- }
- }
- class FT{
- public static String name = "name";
- public static int age = 11;
- }
java基础知识(十一)java反射机制(上)的更多相关文章
- Java开发培训基础知识解析之反射机制
Java是老牌编程语言,是当前应用最广泛的编程语言之一.想要学习Java你就一定要掌握Java基础知识,而反射对于初学Java的人来说绝对是非常重要的知识点.什么是反射?如何理解反射机制?如何使用反射 ...
- java 基础知识三 java变量
java 基础知识 三 变量 1.作用域 {} 包围起来的代码 称之为代码块,在块中声明的变量只能在块中使用 2.常量 就是固定不变的量,一旦被定义,它的值就不能再被改变. 3.变量 变量必须在程序 ...
- Java基础(十一)——反射
一.概述 1.介绍 Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法. 加载完类 ...
- JAVA基础知识之JVM-——使用反射生成并操作对象
Class对象可以获取类里的方法,由Method对象表示,调用Method的invoke可以执行对应的方法:可以获取构造器,由Constructor对象表示,调用Constructor对象的newIn ...
- 《Java基础知识》Java 反射详解
定义 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方法的功能称为java语言的反射 ...
- Java基础系列 - 泛型和反射机制
package com.test5; import java.lang.reflect.Field; import java.lang.reflect.Method; /** * Java泛型和反射机 ...
- 《Java基础知识》Java注解"@"详解
Java注解含义: Java注解,顾名思义,注解,就是对某一事物进行添加注释说明,会存放一些信息,这些信息可能对以后某个时段来说是很有用处的.Java注解又叫java标注,java提供了一套机制,使得 ...
- 《Java基础知识》Java异常处理详解
1. Java 中的异常 前言:Java 中的异常处理是处理程序运行错误时的强大机制之一,它可以保证应用程序的正常流程. 首先我们将了解java异常.异常的类型以及受查和非受查异常之间的区别. 1.1 ...
- Java基础知识:Java实现Map集合二级联动2
2. 定义获取省份的方法,创建一个Map集合,将上一步得到的映射集合赋值给它,使用Map集合的keySet()方法获取该集合中的所有键对象组成的Set 集合,即为省分集合,创建一个Object型一维数 ...
- 《Java基础知识》Java IO流详解
Java IO概念 1. 用于设备之间的数据传输. 2. Java 将操作数据流的功能封装到了IO包中. 3. 数据流流向分:输入流和输出流,操作对象为文件. 4. 流按照操作数据分:字节流(通用)和 ...
随机推荐
- java基础学习02(简单的java程序)
简单的java程序 一.完成的目标 1. 理解java程序的基本组成 2. 如何对程序代码进行注释 3. java标识符的命名规则 4. 了解java中的关键字 5. 使用java定义变量或声明变量 ...
- javascript中的感叹号 "!"
JavaScript中会经常遇到一个操作符:! 这是一个布尔操作符,用于将操作的值强制转换为布尔值并取反.常用场景如下: //条件判断中使用 var a; var b=null; if(!a){ co ...
- 【MySQL】函数IFNULL、设置默认时间
MySql 函数 IFNUll用法说明 IFNULL(expr1,expr2) 如果 expr1 不是 NULL,IFNULL() 返回 expr1,否则它返回 expr2. IFNULL()返回一个 ...
- caffe添加自己的层
首先修改src/caffe/proto/下的caffe.proto,修改好后需要编译 然后修改include/caffe/layers/logwxl_layer.hpp 然后修改src/caffe/l ...
- Python 【第十章】 Django路由
路由可以简单理解就是 URL -> 函数名 例如: /login1/ -> 函数名 urls.py文件中 urlpatterns = [ # url(r'^admin/', admin.s ...
- Python 【第九章】 Django基础
在windows 命令行上安装Django 在CMD命令行中输入以下命令进行安装. pip install Django 在windows python安装目录上会出现 一个django-admin. ...
- fastclick 源码注解及一些基础知识点
在移动端,网页上的点击穿透问题导致了非常糟糕的用户体验.那么该如何解决这个问题呢? 问题产生的原因 移动端浏览器的点击事件存在300ms的延迟执行,这个延迟是由于移动端需要通过在这个时间段用户是否两次 ...
- 在不损坏C盘的情况下为C盘扩容,适用于Win
2016年12月29日14:29:27 参考原文:http://jingyan.baidu.com/article/90808022a6c6b7fd91c80fc8.html 在不损坏磁盘的情况下给某 ...
- FineUI配置文件
<configuration> <configSections> <section name="FineUI" type="FineUI.C ...
- bootstrap学习笔记--bootstrap概览
HTML 5 文档类型(Doctype) Bootstrap 使用了一些 HTML5 元素和 CSS 属性.为了让这些正常工作,您需要使用 HTML5 文档类型(Doctype). 因此,请在使用 B ...