java基础------>Class类

本文详细介绍了Java中的Class类,解释了Class类的作用及其主要方法,包括动态加载类、创建对象及反射操作等。同时,文章还探讨了Class对象的生成方式及原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载自:http://blog.youkuaiyun.com/a379039233/article/details/6158816/

         和 http://blog.youkuaiyun.com/yuebinghaoyuan/article/details/7244123

一,class类有什么用?

   class类的实例表示Java应用运行时的类(class ans enum)或接口(interface and annotation)(每个java类运行时都在JVM里表现为一个class对象,可通过类名.class,类型.getClass(),Class.forName("类名")等方法获取class对象)。数组同样也被映射为为class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。基本类型boolean,byte,char,short,int,long,float,double和关键字void同样表现为 class  对象。

 

二,class类的特征
    class类没有公有的构造方法,它由JVM自动调用(在new对象或者加载-classLoader时)。

    下面的方法作用是打印出对象的class name:

 void printClassName(Object obj) {
         System.out.println("The class of " + obj +
                            " is " + obj.getClass().getName());
   }
  同样可以根据class literal 获得class name:
  System.out.println("The name of class Foo is: "+Foo.class.getName());//你可以将Foo改为void尝试下。
三,class的主要方法

class类的方法还是挺多的。主要是用于得到运行时类的相关信息(可用于反射)。

  重要的几个方法:

1, public static Class<?> forName(String className) :natice 方法,动态加载类。非常重要。
       如在sql中动态加载驱动程序:class.forName(sqlDriver);

2,public T newInstance() :根据对象的class新建一个对象,用于反射。非常重要。
       可用在反射中构建对象,调用对象方法:

       class doubleClass= class.forName("java.lang.Double");

       Object objDouble = doubleClass.newInstance();

       如在javaBean中就应用了这个方法,因为java默认要有一个无参构造函数。

3, public ClassLoader getClassLoader() :获得类的类加载器Bootstrap  ,Extension ,System or user custom      ClassLoader(一般为system classloader)。重要。

 

4,public String getName() :获取类或接口的名字。记住enum为类,annotation为接口。重要

5,public native Class getSuperclass():获取类的父类,继承了父类则返回父类,否则返回java.lang.Object。返回Object的父类为空-null。一般
6,public java.NET.URL getResource(String name) :根据字符串获得资源。

7,其他类 

 public boolean isEnum() :判断是否为枚举类型。

 public native boolean isArray() :判断是否为数组类型。

 public native boolean isPrimitive() :判断是否为基本类型。
 public boolean isAnnotation() :判断是否为注解类型。


public Package getPackage() :反射中获得package,如java.lang.Object 的package为java.lang。

public native int getModifiers() : 反射中获得修饰符,如public static void等 。

public Field getField(String name):反射中获得域成员。

public Field[] getFields() :获得域数组成员。    
public Method[] getMethods() :获得方法。

public Method getDeclaredMethod(String name, Class<?>... parameterTypes):加个Declared代表本类,继承,父类均不包括。

public Constructor<?>[] getConstructors() :获得所有的构造函数。

如此我们可以知道反射可以运行时动态获得类的所有信息,并新建对象(newInstance()方法)。

如我们定义一个类:

public class Test{

   //Constructor

   public Test(){this("");}

   public Test(String name){}

   //Field

   public int id;

   public String name;

   //Method

   public void testMethod(){

 

   }

}
我们可以:

Class c = Class.forName("Test");
Method m[] = c.getDeclaredMethods();
for (int i = 0; i < m.length; i++)
   System.out.println(m[i].toString());//输出testMethod
}

Constructor c[] = cls.getDeclaredConstructors();
for (int i = 0; i < c.length; i++) {
   Constructor ct = c[i];
System.out.println("name = " + ct.getName());//输出两个构造函数信息


java中把生成Class对象和实例对象弄混了,更何况生成Class对象和生成instance都有多种方式。所以只有弄清其中的原理,才可以深入理解。首先要生成Class对象,然后再生成Instance。那Class对象的生成方式有哪些呢,以及其中是如何秘密生成的呢?

Class对象的生成方式如下:

1.Class.forName("类名字符串")  (注意:类名字符串必须是全称,包名+类名)

2.类名.class

3.实例对象.getClass()

通过一段小程序,来观察一下Class对象的生成的原理。

  1. /** 
  2.  
  3.  * 2012-2-6 
  4.  
  5.  * Administrator 
  6.  
  7.  */  
  8.   
  9. /** 
  10.  
  11.  * @author: 梁焕月  
  12.  
  13.  * 文件名:TestClass.java  
  14.  
  15.  * 时间:2012-2-6上午10:01:52   
  16.  
  17.  */  
  18.   
  19. public class TestClass {  
  20.   
  21.    
  22.   
  23. public  static void main(String[] args)  
  24.   
  25. {  
  26.   
  27. try {  
  28.   
  29. //测试Class.forName()  
  30.   
  31. Class testTypeForName=Class.forName("TestClassType");          
  32.   
  33. System.out.println("testForName---"+testTypeForName);  
  34.   
  35. //测试类名.class  
  36.   
  37. Class testTypeClass=TestClassType.class;  
  38.   
  39. System.out.println("testTypeClass---"+testTypeClass);  
  40.   
  41. //测试Object.getClass()  
  42.   
  43. TestClassType testGetClass= new TestClassType();  
  44.   
  45. System.out.println("testGetClass---"+testGetClass.getClass());  
  46.   
  47.    
  48.   
  49. catch (ClassNotFoundException e) {  
  50.   
  51. // TODO Auto-generated catch block  
  52.   
  53. e.printStackTrace();  
  54.   
  55. }  
  56.   
  57.    
  58.   
  59. }  
  60.   
  61. }  
  62.   
  63.  class TestClassType{  
  64.   
  65. //构造函数  
  66.   
  67. public TestClassType(){  
  68.   
  69. System.out.println("----构造函数---");  
  70.   
  71. }  
  72.   
  73. //静态的参数初始化  
  74.   
  75. static{  
  76.   
  77. System.out.println("---静态的参数初始化---");  
  78.   
  79. }  
  80.   
  81. //非静态的参数初始化  
  82.   
  83. {  
  84.   
  85. System.out.println("----非静态的参数初始化---");  
  86.   
  87. }          
  88.   
  89. }  

 

测试的结果如下:

---静态的参数初始化---

testForName---class TestClassType

testTypeClass---class TestClassType

----非静态的参数初始化---

----构造函数---

testGetClass---class TestClassType



根据结果可以发现,三种生成的Class对象一样的。并且三种生成Class对象只打印一次“静态的参数初始化”。 

我们知道,静态的方法属性初始化,是在加载类的时候初始化。而非静态方法属性初始化,是new类实例对象的时候加载。

因此,这段程序说明,三种方式生成Class对象,其实只有一个Class对象。在生成Class对象的时候,首先判断内存中是否已经加载。

所以,生成Class对象的过程其实是如此的:

当我们编写一个新的Java类时,JVM就会帮我们编译成class对象,存放在同名的.class文件中。在运行时,当需要生成这个类的对象,JVM就会检查此类是否已经装载内存中。若是没有装载,则把.class文件装入到内存中。若是装载,则根据class文件生成实例对象。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值