Java 的大 Class 到底是什麼?

推薦閱讀:

作者在之前工作中,面試過很多求職者,發現有很多面試者對Java的 Class 搞不明白,理解的不到位,一知半解,一到用的時候,就不太會用。

想寫一篇關於Java Class 的文章,沒有那麼多專業名詞,希望用通俗的語言能把Java的 Class 這個概念講明白,理解了Class後,Java的反射也就好理解多了。

Class很容易,保證看了就明白,我們先來熟悉一個最基礎的概念,什麼是類?

什麼是類?

這個想必所有的學過面向對象編程語言的同學應該都知道,下面給出正式一點的描述
類就是具備某些共同特徵的實體的集合

比如下面定義一個 Student 類

class Student{
   String name;
   int age;

   public void learn(){
       System.out.println("正在學習");
   }

   public int getAge(){
       return age;
   }

   public void hello(String message){
      System.out.println(message);
   }
}

所有的學生都有一姓名,都有年齡,都要去學習,這些都學生的共性

那麼既然所有的學生都有一些公共的特性,那麼我們Java(其它語言也一樣)語言中,所有的類是不是也都有公共的特性呢?

是不是不太明白?所有的類都有公共的特性? 是的?沒聽錯
我們再定義一個類Book,如下

class Book{
   private float price;
   private String author;
}

所有的書都有 價格,作者等公共的特性(這裏爲了簡單,例子儘可能代碼少點)

所以,不管是上面的Student,Book類,還是Java語言中的自帶類比如String

所有的類,都有下面的一些共性:

  • 所有的類,都有一個類名:比如上面的 Student, BookString類,再加上包名,假如包名是 com.test , 那麼這些類的名字就是
    com.test.Student , com.test.Book, com.test.String
  • 所有的類,都有0個或者多個字段,比如上面的 name,age,price,author
  • 所有的類,都有0個或者多個方法,比如上面的learn()
  • 所有的類,都有修飾符,比如public,private,protected
  • 所有的類,都有0個或者多個靜態方法
  • 等等等

Class到底是什麼?

通過上面的分析我們知道,所有的類都有一些公共特性,那麼我們就定義一個類,來描述這些公共特性,我們暫且把這個類起個類名,叫 Info

其實我們這裏的Info類,就是java中的Class,java中的Class其實就是個普通的類而已,和其它的類沒什麼不一樣的。不信看看Class定義

是不是就是一個普通的類,我們把繼承關係去掉,是不是就是下面這樣了

public class Class {
    ....
}

可不就是個普通的類嘛,只不過類名也叫Class,和java中的關鍵字class,只是首字母大寫了而已,要我說當初就不應該起名叫Class,應該叫Type,就不會有那麼多人誤解了,就不會有人把Classclass這兩個弄的暈頭轉向的傻傻分不清了。

總之一句話:Class就是一個普通的類,這個類描述的是所有的類的公共特性

Class類能幹什麼?

瞭解Class類能幹什麼之前,我們先來擴展一些其它的東西

既然上面我們知道了,所有的類都是有公共特性的,我們定義了一個叫Class的類來描述這些公共特性

那麼是不是所有的類的方法,所有的類的字段,是不是也有公共的特性?
答案是的

是不是有點迷糊? 不要怕,很簡單,舉個例子就知道了。
還是上面的Student,Book類,

  • 所有的類的字段,都有名字。
    比如Book類中的price字段,它的名字是不是"price"
  • 所有的類的字段,都有類型。
    比如Book類中的price字段,它的類型是 float
  • 所有的類的字段,都有修飾符。
    比如Book類中的price字段,它的修飾符是 private

所以這些類的字段公共的特性,我們也可以定義一個類來描述,這個類就是Field
我們看一下JDK中關於Field的定義

是不是和Class類一樣,Field類也是一個普通的類

同理,類中所有的方法,是不是也有公共的特性?
答案:是的

  • 所有的類的方法,都有方法名
    比如Student類中的getAge()方法,它的方法名是 "getAge"
  • 所有的類的方法,都有返回值類型
    比如Student類中的getAge()方法,它的返回值是 int類型
  • 所有的類的方法,都有參數。(無參數也是算是特殊的參數吧)
    比如Student類中的hello(String message)方法,有一個參數,參數的類型是值是 String類型
  • 所有類的方法,都有修飾符號。
    比如Student類中的getAge()方法,它修飾符號是 public

所以這些類的方法的公共的特性,我們也可以定義一個類來描述,這個類就是Method
我們看下JDK中的定義

同樣是一個普通的類

由上面可以,那麼Class類就是通過FieldMethod來描述類中的字段和方法
我們來看一下JDK中Class類中,關於Field和Method的成員

這些數組就是保存類中的字段或者方法的。

扯遠了,回到開頭,Class類能幹什麼?
既然通過上面我們知道了,Class類中保存的是所有類的公共特性,那麼是不是我們通過Class知道某個類中有多少方法,有多少字段,每個字段叫什麼名字,每個字段的類型是什麼,每個方法的方法名是什麼,某個方法有幾個參數,等等

答案是肯定的
那如何通過Class知道你說的這些信息呢?
當然是寫代碼啊,比如我們在程序運行的時候,點擊某個按鈕,打印出某個類的信息,是可以做到的

Class如何使用?

既然上面我們知道了Class能幹什麼了?下面我們簡單的瞭解一下,如何使用Class

如何使用Class?

Class就是一個普通的類啊,使用普通的類就是創建一個對象,才能使用啊
很簡單啊,我們創建一個Class的對象就行了啊,就可以調用對象的各種方法了啊
使用就是這麼簡單

如何獲取一個Class的對象?

我們先看一下JDK中 Class類的構造函數

就這一個構造函數,還是私有的,所以,我們不能直接new一個對象了

如何獲取一個Class的對象?
答案:有以下3種方法,直接上代碼

   public static void main(String[] args){
        //第一種
        Class c1 = String.class;

        //第二種
        String s = "hello,world";
        Class c2 = s.getClass();

        //第三種,以上面的Book類爲例,其實就是動態加載類,注意捕獲異常,因爲類有可能不存在 
        try {
            Class c3 = Class.forName("com.test.Book");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

有了 Class的對象我們怎麼用

我們直接通過一個demo來演示更加的直接,如下

package com.example.demo;

public class Student {
    private String name;
    private int age;

    public static void main(String[] args){
        //一般我們把Class的對象叫字節碼
        Class c = Student.class;

        // 外部普通類
        System.out.println("Student類名是:" + c.getName());
        System.out.println("Student類的簡單類名是:" + c.getSimpleName());
        System.out.println("Student類有" + c.getDeclaredFields().length + "個字段");

        /**
         * ....
         * 我們可以通過 c (也就是Student這個類的對象,或者你也可以叫做Student類的字節碼)
         * 拿到Student類中所有的方法名,方法數,字段名,字段數量,甚至你還可以通過Method來調用方法
         * 只要查查API,熟悉了API,就能做到
         * 暫時我們只打印簡單
         */
    }
}

總結一下:
綜上所述,我們知道了

  • Class就是一個普通的類,就是用來描述一個類的信息的(比如類有幾個字段,幾個方法,名字叫什麼等等 )
  • 可以通過 3 種方法來獲取Class的對象,也就是某個類的字節碼
  • 有個某個類的字節碼以後,我們就知道知道這個類的許多信息了
  • Class一般是在運行時使用,你只要告訴我類名,我就可以知道這個類中有多少方法,有多少字段,怎麼調用等等
  • Filed,Method(還有其它的,我們只說這2個),分別是描述類的字段和類的方法的

關於 Class 的知識就講到這裏,主要是明白 Class 到底是個什麼東西,剩下的就自己查一下API,寫個demo測試一下就行了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章