`

class对象

阅读更多
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反射机制-Class类-Class对象的获取.pdf

    ### JAVA反射机制——Class类与Class对象的获取 #### 概述 在Java语言中,反射是一种强大的功能,允许程序在运行时动态地检查和修改自身的行为。这种能力是通过`java.lang.Class`类实现的,它提供了封装类或接口...

    Java中通过Class类获取Class对象的方法详解

    "Java中通过Class类获取Class对象的方法详解" Java中获取Class对象是Java基础知识中的一个重要部分,通过Class类可以获取Class对象,Class对象是Java虚拟机在加载类时自动构造的。下面将详细介绍通过Class类获取...

    PHP把实例化的class对象永久保存

    PHP把实例化的class对象存入session(session的值写入memcache),不必每次都创建类的实例 听起来有点绕口,其实就是: 1.不管你网站有多大,且有多少个class,用此方法之后每个类只需要实例化一次(除非你重启了服务器),听...

    Java中Class对象详解共2页.pdf.zip

    这份"Java中Class对象详解共2页.pdf.zip"文件虽然只有短短两页,但预计会涵盖Class对象的基本概念、获取Class对象的方式、以及如何使用Class对象进行反射操作等关键内容。 首先,理解Class对象的基本概念至关重要。...

    java元数据——CLass类

    Class对象的创建发生在类加载(java.lang.ClassLoader)的时候,JVM加载一个类的时候首先创建Class对象,然后创建这个类的每个实例的时候都使用这个Class对象。 Class对象的作用是: 1. JAVA 使用 Class 对象来...

    Java中Class对象详解.docx

    Java中的Class对象是Java反射机制的核心,它代表了一个类的信息,包括类的名称、属性、方法等。在Java中,每个类都有一个对应的Class对象,它由Java虚拟机(JVM)在类加载时创建。了解Class对象的生成方式和原理对于...

    简单了解JAVA中类、实例与Class对象

    加载完成后,JVM会为这个类创建一个Class对象,这个对象是类的唯一实例,在Java中这个Class对象是唯一的,并且与类的每个实例共享。 这个Class对象可以看作是类的“模板”,JVM通过这个模板来理解类的结构和行为。...

    Class对象获取的三种方法

    在Java编程语言中,`Class`对象扮演着至关重要的角色,它提供了运行时关于类、接口、数组类、基本类型和枚举类型的反射信息。获取`Class`对象的方法有多种,其中最为常见的便是通过`.class`语法、`Class.forName...

    深入理解Java类型信息(Class对象)与反射机制

    本篇主要是深入对Java中的Class对象进行分析,这对后续深入理解反射技术非常重要,主要内容如下:认识Class对象之前,先来了解一个概念,RTTI(Run-TimeTypeIdentification)运行时类型识别,对于这个词一直是C++中...

    Java反射获取class对象方式解析

    Java反射获取class对象方式解析 Java反射获取class对象方式解析是Java反射机制中的一种重要技术,它可以帮助开发者在运行时获取类的信息和对象实例。下面我们将通过示例代码详细介绍Java反射获取class对象方式解析...

    Class对象和Java反射机制

    其实从某种意义上说,在java中有两种对象:实例对象和Class对象。实例对象是我们平常定义的一个类的实例:  /**  * Created by aristark on 3/28/16.  */  public class Person {  }  然后利用new关键字...

    通过Class类获取对象(实例讲解)

    在Java中,每个类都有一个与之对应的Class对象,该对象包含了类的所有信息,包括构造函数、方法、字段等。通过获取Class对象,我们可以使用newInstance()方法创建一个新的对象实例。 在示例代码中,我们首先获取了...

    STL容器之set的使用(含class对象),内含可运行代码和详细解释

    代码包含set使用中的size,insert,count,find,erase,swap,lower_bound,upper_bound,equal_range方法以及详细例子,并设立类和对象,可以看出set如何对对象进行排序和其他操作。

    Prototype Class对象学习

    `Prototype Class对象`是一个关于如何在JavaScript中使用原型实现类式继承的学习主题。 `Prototype`对象在JavaScript中扮演着关键的角色,它是每个对象的属性,允许对象之间共享方法和属性。当一个对象被创建时,它...

    用原生JS获取CLASS对象(很简单实用)

    标题“用原生JS获取CLASS对象(很简单实用)”意味着我们将要探讨如何通过原生JavaScript代码实现获取页面上具有特定class的DOM元素对象,并进行进一步操作。 首先,我们来看如何定义一个函数`getElementsClass`,它...

    详解ECMAScript6入门--Class对象

    在ECMAScript 6(简称ES6)中,引入了一个重要的新特性——Class对象,它为JavaScript提供了更接近传统面向对象编程语言的语法结构。在ES5以前,JavaScript使用构造函数和原型链来实现面向对象的特性,而ES6的Class...

    python实现class对象转换成json/字典的方法

    本文实例讲述了python实现class对象转换成json字典的方法。分享给大家供大家参考,具体如下: # -*- encoding: UTF-8 -*- class Student: name = '' age = 0 def __init__(self, name, age): self.name = name ...

    Java泛型的用法及T.class的获取过程解析

    首先,我们使用`getClass()`方法获取当前类的Class对象,然后使用`getGenericSuperclass()`方法获取当前类的父类的Type对象。最后,我们使用`getActualTypeArguments()`方法获取Type对象中的实际类型参数,然后将其...

Global site tag (gtag.js) - Google Analytics