`
sassds
  • 浏览: 149717 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java中Class类工作原理详解

    博客分类:
  • java
阅读更多

1.Class对象

    Class对象包含了与类相关的信息。事实上,Class对象就是用来创建类的所有的"普通"对象的。

    类是程序的一部分,每个类都有一个Class对象。换言之,每当编写并且编译了一个新类,就会产生一个Class对象(恰当地说,是被保存在一个同名 的。class文件中)。在运行时,当我们想生成这个类的对象时,运行这个程序的Java虚拟机(JVM)首先检查这个类的Class对象是否已经加载。 如果尚未加载,JVM就会根据类名查找。class文件,并将其载入。

    一旦某个类的Class对象被载入内存,它就被用来创建这个类的所有对象。看下面示例。

    SweetShop.java

    package com.zj.sample;

    class Candy {

    static {

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

    }

    }

    class Gum {

    static {

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

    }

    }

    class Cookie {

    static {

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

    }

    }

    public class SweetShop {

    public static void main(String[] args) {

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

    new Candy();

    System.out.println("After creating Candy");

    try {

    Class.forName("com.zj.sample.Gum");

    } catch (ClassNotFoundException e) {

    System.out.println("Couldn't find Gum");

    }

    System.out.println("After Class.forName("Gum")");

    new Cookie();

    System.out.println("After creating Cookie");

    }

    }

    结果:

    inside main

    Loading Candy

    After creating Candy

    Loading Gum

    After Class.forName("Gum")

    Loading Cookie

    After creating Cookie

    2.获取Class实例的三种方式

    1)利用对象调用getClass()方法获取该对象的Class实例。

    2)使用Class类的静态方法forName(),用类的名字获取一个Class实例。

    3)运用。class的方式来获取Class实例,对于基本数据类型的封装类,还可以采用。TYPE来获取相对应的基本数据类型的Class实例。

    3.Class.forName

    上面的示例中:

    Class.forName("com.zj.sample.Gum");

    这个方法是Class类(所有Class对象都属于这个类)的一个static成员。Class对象就和其它对象一样,我们可以获取并操作它的引用。 forName()是取得Class对象的引用的一种方法。它是用一个包含目标类的文本名的String作输入参数,返回的是一个Class对象的引用。

    4.类字面常量

    Java还提供了另一种方法来生成对Class对象的引用,即使用"类字面常量"。对上述程序来说,可以是:

    com.zj.sample.Gum.class;

    5.关键字instanceof

    关键字instanceof返回一个布尔值,判断是不是某个特定类型的实例。

    if(x instanceof Dog) ((Dog)x)。bark();

    6.获取Class实例

    package com.zj.sample;

    class Point {

    int x, y;

    }

    class ClassTest {

    public static void main(String[] args) {

    Point pt = new Point();

    Class c1 = pt.getClass();

    System.out.println(c1.getName());

    try {

    Class c2 = Class.forName("com.zj.sample.Point");

    System.out.println(c2.getName());

    } catch (Exception e) {

    e.printStackTrace();

    }

    Class c3 = Point.class;

    System.out.println(c3.getName());

    Class c4 = int.class;

    System.out.println(c4.getName());

    Class c5 = Integer.TYPE;

    System.out.println(c5.getName());

    Class c6 = Integer.class;

    System.out.println(c6.getName());

    }

    }

    结果:

    com.zj.sample.Point

    com.zj.sample.Point

    com.zj.sample.Point

    int

    int

    java.lang.Integer

    7.Class的其他方法

    1)Class.newInstance()使用所选的Class对象生成该类的新实例。它调用了缺省(无参数)的类构造器生成新的对象。所以使用 newInstance()创建的类必须有一个缺省构造器。对于newInstance()来说,可以在原先没有任何对象存在的情况下,使用它创建一个新 的对象。

    利用newInstance()实例化一个对象:

    package com.zj.sample;

    class Point {

    static {

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

    }

    int x, y;

    }

 

class ClassTest {

    public static void main(String[] args) {

    try {

    Class c = Class.forName("com.zj.sample.Point");

    Point pt = (Point) c.newInstance();

    } catch (Exception e) {

    e.printStackTrace();

    }

    }

    }

    结果:

    Loading Point

    2)Class.isInstance()方法提供了一种动态地调用instanceof运算符的途径。

    3)Class.getInterfaces()方法返回Class对象的数组,这些对象代表的是某个Class对象所包含的接口。

    4)如果有一个Class对象,那么就可以通过getSuperclass()获取它的直接基类。这个方法自然也是返回一个Class引用,所以可以进一步查询其基类。这意味着在运行时,可以找到一个对象完整的类层次结构。

    5)Class类支持反射的概念,Java附带的库java.lang.reflect包含了Field、Method以及Constructor类 (每个类都实现了Member接口)。这些类型的对象是由JVM在运行时创建的,用以表示未知类里对应的成员。这样可以使用Constructor创建新 的对象,用get()和set()方法读取和修改与Field对象关联的字段,用invoke()方法调用与Method对象关联的方法。另外,还可以调 用getFields()、getMethods、getConstrucotrs()方法,返回表示字段、方法以及构造器的对象的数组。

    8.利用反射API察看未知类的构造方法与方法

    package com.zj.sample;

    import java.lang.reflect.Constructor;

    import java.lang.reflect.Method;

    class Point {

    static {

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

    }

    int x, y;

    void output() {

    System.out.println("x=" + x + "," + "y=" + y);

    }

    Point(int x, int y) {

    this.x = x;

    this.y = y;

    }

    }

    class ClassTest {

    public static void main(String[] args) {

    try {

    Class c = Class.forName("com.zj.sample.Point");

    Constructor[] cons = c.getDeclaredConstructors();

    for (int i = 0; i < cons.length; i++)// 返回所有声明的构造方法

    {

    System.out.println(cons[i]);

    }

    Method[] ms = c.getDeclaredMethods();

    for (int i = 0; i < ms.length; i++)// 返回所有声明的方法

    {

    System.out.println(ms[i]);

    }

    } catch (Exception e) {

    e.printStackTrace();

    }

    }

    }

    结果:

    Loading Point

    com.zj.sample.Point(int,int)

    void com.zj.sample.Point.output()

    9.动态调用一个类的实例(完全没有出现point这个名字)

    package com.zj.sample;

    import java.lang.reflect.Constructor;

    import java.lang.reflect.Method;

    class Point {

    static {

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

    }

    int x, y;

    void output() {

    System.out.println("x=" + x + "," + "y=" + y);

    }

    Point(int x, int y) {

    this.x = x;

    this.y = y;

    }

    }

    class ClassTest {

    public static void main(String[] args) {

    try {

    Class c = Class.forName("com.zj.sample.Point");

    Constructor[] cons = c.getDeclaredConstructors();

    Class[] params = cons[0].getParameterTypes();// 察看构造器的参数信息

    Object[] paramValues = new Object[params.length];// 构建数组传递参数

    for (int i = 0; i < params.length; i++) {

    if (params[i].isPrimitive())// 判断class对象表示是否是基本数据类型

    {

    paramValues[i] = new Integer(i);

    }

    }

    Object o = cons[0].newInstance(paramValues);// 创建一个对象的实例

    Method[] ms = c.getDeclaredMethods();// 调用方法

    ms[0].invoke(o, null);// 用指定的参数调用(output方法没有参数,null)

    } catch (Exception e) {

    e.printStackTrace();

    }

    }

    }

    结果:

    Loading Point

    x=0,y=1

分享到:
评论

相关推荐

    java反射机制原理详解.docx

    我们创建一个类,通过编译,生成对应的.calss文件,之后使用java.exe加载(jvm的类加载器)此.class文件,此.class文件加载到内存以后,就是一个运行时类,存在缓存区,那么这个运行时类的本身就是一个class的实例 ...

    学习Java中Class类及其用法

    分为三大部分,主要内容有Class类原理详解、用法及泛化,需要的朋友可以参考下

    java反射原理详解

    很好的有百科名片 JAVA反射机制:“程序运行时,允许改变...换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。

    Java_ClassLoader详解

    Java_ClassLoader详解,解说java类的加载的原理,让你轻松了解java的类加载

    【Java面试+Java学习指南】 一份涵盖大部分Java程序员所需要掌握的核心知识

    Java中的Class类和Object类 Java异常 解读Java中的回调 反射 泛型 枚举类 Java注解和最佳实践 JavaIO流 多线程 深入理解内部类 javac和javap Java8新特性终极指南 序列化和反序列化 继承、封装、多态的实现原理 容器...

    Java的 Class(类)文件结构详解

    了解Class文件的结构组成,对于我们后续的JVM以及Java原理深入学习是很有帮助的,因为Class文件帮我们默默的做了很多事,比如、为什么对象方法中可以直接使用this变量?!本文将带领大家,一步步,从开头到结尾,...

    Java工程师面试复习指南

    Java中的Class类和Object类 Java异常 解读Java中的回调 反射 泛型 枚举类 Java注解和最佳实践 JavaIO流 多线程 深入理解内部类 javac和javap Java8新特性终极指南 序列化和反序列化 继承封装多态的实现原理 集合类 ...

    java基础案例与开发详解案例源码全

    13.2 JavaIO原理332 13.3 流类结构333 13.3.1 InputStream和OutputStream333 13.3.2 Reader和Writer334 13.4 文件流336 13.4.1 FileInputStream和FileOutputStream336 13.4.2 FileReader和FileWriter338 13.5 缓冲流...

    Java生产环境下性能监控与调优详解.7z

    Java生产环境下性能监控与调优详解 本课程将为你讲解如何在生产环境下对Java应用做性能监控与调优;通过本课程,你将掌握多种性能监控工具应用,学会定位并解决诸如内存溢出、cpu负载飙高等问题;学会线上代码调试...

    疯狂JAVA讲义

    学生提问:既然内部类是外部类的成员,是否可以为外部类定义子类,在子类中再定义一个内部类来重写其父类中的内部类? 211 6.7.4 局部内部类 211 6.7.5 匿名内部类 212 6.7.6 闭包(Closure)和回调 215 6.8 ...

    java 编写文件上传类简单易用

    这两个步骤主要的操作有两个,一个是从一个数组中找出另一个数组的位置,类似于 String 类中的 indexOf 的功能,另一个是从一个数组中提取出另一个数组, 类似于 String 类中的 substring 的功能,为此我们可以专门...

    Java的动态代理机制详解

     在java的动态代理机制中,有两个重要的类或接口,一个是 InvocationHandler(Interface)、另一个则是 Proxy(Class),这一个类和接口是实现我们动态代理所必须用到的。首先我们先来看看java的API帮助文档是怎么样对...

    Java多线程实现四种方式原理详解

    1.继承Thread类,重写run方法 ...后面两种可以归结成一类:有返回值,通过Callable接口,就要实现call方法,这个方法的返回值是Object,所以返回的结果可以放在Object对象中 1. 继承Thread类 public class Thread

    Java进阶教程解密JVM视频教程

    * 在字节码与类加载技术章节,会从一个 class 文件开始分析其每一字节的含义。学习字节码指令的的运行流程,字节码指令与常量池、方法区的关系。掌握条件分支、循环控制、异常处理、构造方法在字节码级别的实现原理...

    Java JVM详解

    本文详细讲解了JVM(Java Virtual Machine)的方方面面,首先由java的特性来描绘JVM的大致应用,再细细阐述了JVM的原理及内存管理机制和调优.最后讲述了与JVM密切相关的Java GC机制. 本文内容大多来自网络,但内容十分...

    java面试题,180多页,绝对良心制作,欢迎点评,涵盖各种知识点,排版优美,阅读舒心

    【基础】一个".java"源文件中是否可以包含多个类(不是内部类)?有什么限制? 30 【基础】Anonymous Inner Class(匿名内部类)是否可以继承其它类?是否可以实现接口? 30 【基础】Java 中的final关键字有哪些用法?...

Global site tag (gtag.js) - Google Analytics