基本數據類型vs對象類型


基本數據類型vs對象類型

當你閱讀這篇文章的時候,可能已經知道了Java是雙類型的系統,也就是基本數據類型和對象類型,簡稱基本類型和對象。Java中有8個預定義的基本類型,它們的名字都是保留的關鍵字。常見的基本類型有int、double和boolean。Java中所有其他的類型包括用戶自定義的類型,它們必然也是對象類型(我說”必然”是因為數組類型有點例外,與基本類型比數組更像是對象類型)。每一個基本類型都有一個對應的對象包裝類,比如int的包裝類是Integer,double的包裝類是Double,boolean的包裝類是Boolean。

基本類型基於值,而對象類型則基於引用。與基本類型相關的爭議都源於此。為了說明它們的不同,先來看一下兩個聲明語句。第一個語句使用的是基本類型,第二個使用的是包裝類。

int n1 = 100;

Integer n2 = new Integer(100);

使用新添加到JDK5的特性自動裝箱以后,第二個聲明可以簡化成:

Integer n2 = 100;

但是,底層的語義並沒有發生改變。自動裝箱簡化了包裝類的使用,減少了程序員的編碼量,但是對運行時並沒有任何的改變。

圖1展示了基本類型n1和包裝對象類型n2的區別。

 

 n1持有一個整數的值,但是n2持有的是對一個對象的引用,即那個對象持有整數的值。除此之外,n2引用的對象也包含了一個對Double對象的引用。

 

內存的使用

Java中的double總是占據內存的64個比特,但是引用類型的字節數取決於JVM。我的電腦運行64位Win7和64位JVM,因此在我的電腦上一個引用占用64個比特。根據圖1,一個double比如n1要占用8個字節(64比特),一個Double比如n2要占用24個字節——對象的引用占8個字節,對象中的double的值占8個字節,對象中對Double對象的引用占8個字節。此外,Java需要使用額外的內存來支持對象的垃圾回收,但是基本類型不需要。

 

package mytest;

import java.util.Date;

public class Test {
/**
 * @param n 矩陣n*n
 * @param type 類型 1:double 2:Double
 * @return 獲得存儲所使用的字節數
 */
    public static long getBytesUsingPrimitives(int n,int type){

      System.gc();// force garbage collection
      long memStart = Runtime.getRuntime().freeMemory();
      // put some random values in the matrix
      switch(type){
          case 1:
              double[][] a = new double[n][n];
              for (int i = 0;  i < n;  ++i){
                  for (int j = 0; j < n;  ++j)
                      a[i][j] = Math.random();
                }
              break;
          case 2:
              Double[][] ax=new Double[n][n];
              for (int i = 0;  i < n;  ++i){
                  for (int j = 0; j < n;  ++j)
                      ax[i][j] = Math.random();
                }
              break;
          default:
              break;
      }

      long memEnd = Runtime.getRuntime().freeMemory();

      return memStart - memEnd;
    }
    
    
    //創建double類型矩陣n*m
    public static double[][] create(int n,int m){
        double[][] a = new double[n][m];
        for (int i = 0;  i < n;  ++i){
            for (int j = 0; j < n;  ++j)
                a[i][j] = Math.random();
          }
        return a;
    }
    //創建Double類型矩陣n*m
    public static Double[][] createD(int n,int m){
        Double[][] a=new Double[n][n];
        for (int i = 0;  i < n;  ++i){
            for (int j = 0; j < n;  ++j)
                a[i][j] = Math.random();
          }
        return a;
    }
    /**
     * 創建矩陣,並使兩個矩陣相乘
     * 返回 運行時長
     */
    public static long multiply(int x1,int y1,int x2,int y2,int type){
        Date d1=null;
        switch(type){
        case 1:
            double[][] a=create(x1,y1);
            double[][] b=create(x2,y2);
            d1=new Date();
            if (!checkArgs(y1, x2))
                throw new IllegalArgumentException("Matrices not compatible for multiplication");
            
            int nRows = a.length;
            int nCols = b[0].length;

            double[][] result = new double[nRows][nCols];

            for (int rowNum = 0;  rowNum < nRows;  ++rowNum){
                for (int colNum = 0;  colNum < nCols;  ++colNum){
                        double sum = 0.0;

                        for (int i = 0;  i < a[0].length;  ++i)
                            sum += a[rowNum][i]*b[i][colNum];

                        result[rowNum][colNum] = sum;
                  }
              }
            break;

        case 2:
            Double[][] ax=createD(x1,y1);
            Double[][] bx=createD(x2,y2);
            d1=new Date();
            if (!checkArgs(y1, x2))
                throw new IllegalArgumentException("Matrices not compatible for multiplication");
            
            int nRowsx = ax.length;
            int nColsx = bx[0].length;

            Double[][] resultx = new Double[nRowsx][nColsx];

            for (int rowNum = 0;  rowNum < nRowsx;  ++rowNum){
                for (int colNum = 0;  colNum < nColsx;  ++colNum){
                        Double sum = 0.0;

                        for (int i = 0;  i < ax[0].length;  ++i)
                            sum += ax[rowNum][i]*bx[i][colNum];

                        resultx[rowNum][colNum] = sum;
                  }
              }
            break;
            default:
                break;

        }

      Date d2=new Date();
      return d2.getTime()-d1.getTime();
    }
    

    private static boolean checkArgs(int y1, int x2) {
        if(y1!=x2)
            return false;
        
        return true;
    }
    
    public static void main(String[] args){
        //運行結果,並不是保持不變,這里是平均值
        System.out.println(getBytesUsingPrimitives(1000, 1));//字節數統計    7585424
        System.out.println(getBytesUsingPrimitives(1000, 2));//         28646800

        System.out.println(multiply(1000,1000,1000,1000,1));//所用時間 12773
        System.out.println(multiply(1000,1000,1000,1000,2));//      39017
    }

}

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM