[Think in Java]第2章 一切都是對象

来源:https://www.cnblogs.com/seanho/archive/2019/07/02/11123862.html
-Advertisement-
Play Games

[Think in Java]第2章 一切都是對象 如果我們說另一種不同的語言,那麼我們就會發覺有一個有些不同的世界 -- Luduing Wittgerstein 儘管Java基於C++,但相比之下,Java是一種更純粹的面向對象程式設計語言. Java語言假設我們只進行面向對象的程式設計(OOP ...


[Think in Java]第2章 一切都是對象

如果我們說另一種不同的語言,那麼我們就會發覺有一個有些不同的世界

-- Luduing Wittgerstein

儘管Java基於C++,但相比之下,Java是一種更純粹的面向對象程式設計語言.

Java語言假設我們只進行面向對象的程式設計(OOP)。

2.1 用引用操縱對象

每種語言都有自己操縱記憶體中元素的方式,1. 直接操縱 2. 或者基於某種特殊語法的間接表示。

java中,儘管一切都看作是對象了,但操作的標識符實際上是對象的一個引用(reference)

引用可以單獨存在,你擁有一個引用,並不一定需要有對象和它關聯。

 String s;

這裡創建了一個引用,並不是對象。如果此時向s發送消息,那麼會報運行時錯誤,因為它實際上並沒有和任何對象關聯。更加安全的做法是:創建一個引用的同時便進行初始化

 String good = “good”;

這種創建方式是java語言的一個特性:字元串可以用帶引號的文本初始化。更通用的方式是用new。

2.2 必須由你創建所有對象

一個引用被創建了,就希望它能與一個新的對象相關聯。通常用new操作符來實現這一目的,是以new關鍵字進行對象的初始化,new關鍵字的意思是:”給我一個新的對象”(上面的例子可以寫成)

 String good = new String("good");

表示: "給我一個新的字元串",而且通過提供一個初始字元串,給出了怎樣產生這個String的信息!

2.2.1 對象存儲到什麼地方

素質三連問:程式運行時,對象是怎麼進行放置安排的?記憶體是怎麼樣分配的?你個垃圾會嗎?

  1. 寄存器 最快的存儲區

  2. 棧 位於通用RAM

  3. 堆 通用記憶體池

  4. 常量存儲

  5. 非RAM存儲

(更加詳細的內容,參考《深入理解JVM》)

2.2.2 特例:基本類型 (由父標題推出:這些對象是Java已經幫你創建好了的)

基本類型之所以要特殊對待,是因為new將對象存儲在“堆“里,故用new創建一個對象——特別是小的,簡單的變數,往往不是很有效。因此,不用new創建變數,針對基本變數創建一個並非是引用的”自動“變數,這個變數直接存儲”值“,並置於棧中,因此更加高效。

java的基本類型的大小是固定的,這也是可移植性的原因之一!

需要註意的是 boolean 沒有確定大小,只有字面值 truefalse

 //這裡要有一張基本類型的總結圖

基本類型有著對應的包裝類,使得可以在對堆中創建一個非基本對象,用來表示對應的基本類型。

 char c = "x";
 Character ch = new Character(c);
 //或者
 Character ch = new Character("x");

Java SE5 有自動裝箱和拆箱的功能。

 Character ch = "x"; //基本類型轉換成包裝類型 ,裝箱
 char c = ch; //包裝類型反向轉換基本類型 ,拆箱
 //包裝類的後面再詳細介紹!

高精度數字 :以調用方法的形式進行運算,運算速度會比較慢;犧牲速度換取了精度!

  1. BigInteger

    支持任意精度的整數,不會丟失任何數據

  2. BigDecimal

    支持任何精度的定點數,例如貨幣匯率的計算!

2.2.3 Java中的數組

java中的數組需要被初始化,而且不能超出數據的範圍,這種範圍檢查需要以少量的記憶體開銷和運行時的下表檢查為代價的!但由此換來了安全性和效率的提高,小小的記憶體開銷可以說很值得了!

當創建一個數組對象時,就是創建了一個引用數組,並且引用都會自動被初始化為一個特定值,該值擁有自己的關鍵字null!一旦java看到了null,就知道這個引用還沒有指向某個對象,在使用任何引用時,都要為其指定一個對象! ( 關於數組更詳細的內容,見後面章節!)

2.3 永遠不要銷毀對象 (對應著JVM的垃圾回收機制)

2.3.1 作用域

作用域決定了在其內定義的變數名的可見性和生命周期!

註意代碼

 //這是c++,較大的作用域的變數可以”隱藏”!
 {
     int x = 12;
    {
         int x = 24; //在java中,非法的,x在之前已經被使用了
    }
 }

2.3.2 對象的作用域

java對象不具備和基本類型的生命周期。當用new創建了一個java對象時,它可以存活於作用域之外。

 {
     String s = new String("a String");
 }//end of scope

此時,引用s在作用域就是花括弧內,超過該區域無法再訪問這個對象,但是s指向的String對象仍繼續占據記憶體空間。

問題素質三連問:如何防止這些超過了作用域卻依舊存活在記憶體空間的對象撐爆你的記憶體,讓你的程式終止呢?

java有垃圾回收器(GC,garbige collector),用來監視用new創建的所有對象,那些不再被引用的對象的記憶體空間將會被釋放掉,以便給新對象使用!

吹一波java的垃圾回收機制:不需要關心對象的銷毀,消除了記憶體泄漏的顧慮一定程度上!

2.4 創建新的數據類型 :類

用class 關鍵字來聲明類

 class ATypeClass {   /*class body*/     }

用new來創建這個類型的對象

 ATypeClass a = new ATypeClass();

2.4.1 欄位和方法

類中有兩種元素: 1.欄位(也叫數據類型)和方法(也叫成員函數)

欄位可以是任意類型的對象,可以通過其引用與其進行通信,也可以是基本類型的一種。

如果欄位是某個對象的引用,那必須初始化該引用(就是用new一下)

每個對象都有其欄位空間;普通欄位不能在對象間共用。

 //定義一個類
 class DataOnly{
     int i;
     double d;
     boolean b;
 }
 //創建對象
 DataOnly dataOnly = new DataOnly();

給欄位賦值

 dataOnly.i = 47;
 dataOnly.d = 40.0;
 dataOnly.b = false;

給對象欄位賦值

 myPlane.leftTank.capacity = 100;

基本成員預設值

如果類的某個成員是基本數據類型,即使沒有初始化(既沒有new一下)java也會自動給它一個預設值。

基本類型預設值
boolean false
chat '\u0000'(null)
byte (byte)0
short (short)0
int 0
long 0.L
float 0.0f
double 0.0d

java會自動幫你初始化這些基本類型的成員變數,但是這種方法並不適用於局部變數(幾並非某個類的欄位)。如果某個方法中定義了:

 int x;

那麼變數x得到的可能是任意值,而不會被自動初始化為0,java在編譯時會返回一個錯誤,告訴你這個局部變數沒有初始化

2.5 方法,參數和返回值

方法的基本組成:名稱,參數,返回值,方法體

 ReturnType methodName( /* Argument list*/) {
     /*Method body*/
 }

返回類型:調用方法之後從方法返回的值

參數列表:要傳給方法的信息類型和名稱

方法簽名=方法名+參數列表 ,它唯一地標識出某個方法

方法是類的一部分,只能通過對象調用(當然也有直接類調用的,static方法就是針對類調用的,後詳解 見2.6.3)

方法調用方法:

 objectName.methodName(arg1,arg2);
 
 int x = a.f(); //向對象發送消息

返回值的類型必須要和x的類型相容!

2.5.1 參數列表

方法的參數列表指定要傳遞給方法什麼樣的信息,採用的都是對象的形式。在列表中指定對象的類型和名字,但這裡實際上傳遞的是對象的引用。

例子:接受String為參數,返回該字元串長度的兩倍

int storage(String s){
    return s.length()*2;
}

這裡s一旦傳遞給此方法,就可以把他當作其他對象一樣進行處理。如果不想返回任何值,

void nothing(){
 	/****/
}

2.6 構建一個Java程式

2.6.1 名字可見性

java使用包名來解決文件名字衝突的問題,創建名字空間來唯一確定一個類的位置

net.mindview.utility.fobiles

com.sean.Intruduce.class

2.6.2 運用其他構件(導入其他包內的類)

使用import關鍵字

import java.util.ArrayList; //導入指定某個類
import java.util.* //導入指定某個包下的所有類

2.6.3 static關鍵字

static 出現的兩種原因:

  1. 只想為某特定域分配單一存儲空間

  2. 即使沒創建對象,也能調用這個方法

在欄位前加上 static 就定義了一個靜態變數

class StaticTest{
    static int i = 47;
}
StaticTest st1 = new StaticTest();
StaticTest st2 = new StaticTest();

這裡的 st1.i和st2.i指向同一個存儲空間,具有相同的值48.//媽的,為什麼是48

static的引用方法

  1. 通過一個對象去定位它,st1.i;

  2. 通過類名直接引用,StaticTest.i;

 

對於方法而言,也是類似的。

class Person{
    staic void hello( ... );
}

引用方法:

//通過對象來調用靜態方法
Person p = new Person();
p.hello();

//類名直接調用靜態方法
Person.hello();

2.7 第一個java程式

//HelloDate.java
import java.util.*;
public class HelloDate{
    public static void main(String[] args){
        System.out.print("Hello. It's:");
        System.out.print(new Ddate());
    }
}

import關鍵字聲明要使用的包, java.lang是預設導入到每個java文件中的,所以他的類可以直接被使用.但是這裡java.lang裡面沒有Date類,所以得導入有Date類的包. 也可以具體的顯示導入哪個類

import java.util.Date

類的名字和文件名要相同.main

2.7.1編譯和運行

//編譯java文件
javac HelloDate.java

//運行
java HelloDate

2.8註釋和嵌入式文檔

// 這是當行註釋

/*
這是多行註釋...
這是多行註釋...
*/

/**
這是文檔註釋,開頭多了一個*號.
*/

 

2.8.1 註釋文檔

使用javadoc 來提取註釋以及特殊的標簽,並把相鄰的類和方法都抽取出來,輸出一個HTML文件,形成一份說明文檔

2.8.1 語法

javadoc的兩種方式

  1. 嵌入HTML

  2. 文檔標簽

獨立文檔標簽是用@開頭的命令,並且是在行首, 行內的@ 需要用花括弧內,才能視為標簽

註釋文檔的三種類型

  1. 類 位於類定義之前

  2. 域 域定義之前 (感覺叫變數註釋比較容易理解)

  3. 方法 方法定義之前

例子

/**這是類註釋*/
public class Documents{
    /**這是域註釋*/
    int i;
    /**這是方法註釋*/
    public void f(){.....}
}

需要註意的是:javadoc只能對public和protected成員進行文檔註釋, private和包內訪問成員的註釋會被忽略掉 (不過可以使用 -private 進行標記,達到被輸出的效果)

2.8.3 嵌入HTML

可以對註釋文檔加上html標簽進行格式上的優化,因為javadoc輸出的就是HTML文件格式

例如:

/**
*<pre>
*System.out,print(new Date());
*</pre>
*
*here is the list:
*<ol>
*<li> item one
*<li> item two
*</ol>
*/

不需要自己加標題 (h1,hr)之類的標簽,javadoc自己會生成標題.不然會衝突

 

2.8.4 一些標簽的實例

  1. @see 引用其他類

    格式:

    @see classname
    @see fuuly-qualified-classname
    @see fully-qualified-classname#method-name
    
  2. {@link package.class#member label}

    和@see類似, 用於行內,且用label作為超鏈接文本.

  3. {@docRoot} 生成到根目錄的相對路徑

  4. {@inheritDoc} 表示: 從當前這個類的最直接父類中繼承相關文檔到當前的文檔註釋中

  5. @version 版本信息

    格式: @version version-information

  6. @author 作者信息

  7. @since 最早的版本

  8. @param 用於方法中

    格式: @param parameter-name description

  9. @return

    格式: @return description ,用於描述返回值的含義

  10. @throws 拋出異常

  11. @deprecated

2.9 編碼風格

  1. 類名的首字母要大寫,如果幾個單片語成,把它們合在一起

    class AllTheColorsOfTheRainbow{....}

  2. 欄位以及對象引用名稱等,第一個字母採用小寫

    class AllTheColorsOfTheRainbow{
    	int anIntegerRepresentRainboow;
    	void changeTheValue(int newValue){....}
    }
    

     


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本人在 .NET 轉JAVA 的路上 ,也在學習SpringBoot相關知識,這裡記錄一下在Springboot中實現文件上傳下載的核心代碼 源碼下載地址: https://github.com/struggle0903/SpringBootfiledemo.git ...
  • 點擊屏幕拍打你的翅膀。當你飛過屏幕時,註意黑烏鴉。 下載地址 ...
  • 看一個數組的子集有多少,其實就是排列組合, 比如:[0,1] 對應的子集有:[] [0] [1] [1,1] 這四種。 一般對應有兩種方法: 位運算 和 回溯 。 這裡先使用位運算來做。 位運算 一個長度為n的數組,對其做排列組合,可以理解為:這n個數字中,有哪些是存在的,哪些是不存在的。 例如,數 ...
  • Python模塊和包 一、模塊 1. 什麼是模塊 常見的場景:一個模塊就是一個包含了Python定義和聲明的文件,文件名就是模塊名字加上.py的尾碼。 但其實import載入的模塊分為四個通用類別: 1 使用Python編寫的代碼(.py文件) 2 已被編譯為共用庫或DLL的C或C++擴展 3 包好 ...
  • 一、檢視一個函數相同的另一種方法 利用屬性:函數._name 從結果來看他們的本體都是hello函數 二、裝飾器 1.定義:在不改動代碼的基礎上無限擴展函數功能的一種機制,本質上來講,裝飾器是一個返回函數的高階函數。 2.裝飾器的使用:使用@愈發,即在每次要擴展到函數定義前使用@+函數名。 3.裝飾 ...
  • 個人網站: lipeiguan.top 以後會慢慢轉移到個人網站, 歡迎大家收藏^ . ^ 寫在前面 我們在開發一個網站的時候, 經常需要實現網站的用戶系統. 這個時候我們需要實現用戶註冊、用戶登錄、用戶認證、註銷、修改密碼等一系列功能. 如果我們都是自己實現的話, 不是不可以, 只是有些浪費時間. ...
  • 老雷socket編程之PHP利用socket擴展實現聊天服務 socket聊天服務原理 PHP有兩個socket的擴展 sockets和streamssockets socket_create(AF_INET, SOCK_STREAM, SOL_TCP) socket_write socket_re ...
  • 老雷socket編程之常見網路協議 1.ip IP協議是將多個包交換網路連接起來,它在源地址和目的地址之間傳送一種稱之為數據包的東西, 它還提供對數據大小的重新組裝功能,以適應不同網路對包大小的要求。 2.TCP 傳輸控制協議 TCP(Transmission Control Protocol 傳輸 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...