天天看點

java基礎學習(一):java語言概述與開發環境

  哈哈哈哈,别問我為什麼從python機器學習開始學起了java,因為時代在變,也有了自己的新目标,現在已經是大二下學期啦,但是現在開始學習也不晚,大家一起努力加油呀。這裡的話,我會把比較重要而且容易忘的知識點記錄在這裡,就當是我的學習筆記,也希望大家能夠捧捧場。

1.1 java程式運作機制

  首先,計算機進階語言按程式的執行方式可以分為編譯型和解釋型兩種。

  編譯型語言是指使用專門的編譯器,針對特定平台(作業系統)将某種進階語言源代碼一次性“翻譯”成可被該平台硬體執行的機器碼(包括機器指令和操作數),并包裝成該平台所能識别的可執行性程式的格式,這個轉換過程稱為編譯(Compile)。編譯生成的可執行程式可以脫離開發環境,在特定的平台上獨立運作。

  現有的C、C++等進階語言都屬于編譯型語言。

  解釋型語言是指使用專門的解釋器對源程式逐行解釋成特定平台的機制碼并立即執行的語言。解釋語言通常不會進行整體性的編譯和連結處理,解釋型語言相當于把編譯型語言中的編譯和解釋過程混合到一起同時完成。

  現有的python,javaScript等語言都屬于解釋型語言。

  這裡的話,深有體會。相信學過C語言和Python語言的同學都能感覺到,C語言運作前需要編譯,如果編譯不成功,就不能執行該程式,也就是說代碼一定要沒文法毛病才可以正常運作;但是python,你無論何時都可以運作,它會一步一步執行到結尾或者出錯的地方為止,無論你的代碼是否有文法錯誤,都能夠執到錯誤的代碼前。是以這個時候,針對這兩種不同的編譯機制的語言,debug的方法,或者檢查程式的方法會有所不同。

1.1.1 java程式的運作機制和JVM

  這裡java就很驕傲了,java語言說它既不是純粹的編譯型語言,也不是純粹的解釋型語言。java在兩者之間,同時具備兩者的特性。由java語言編寫的程式需要經過編譯步驟,但這個編譯步驟并不會生成特定平台的機器碼,而是生成一種與平台無關的位元組碼(也就是*.class檔案)。這種位元組碼不是一個平台可以直接執行的,必須使用java解釋器來解釋執行。是以很好解釋,java程式的執行過程必須經過先編譯、後解釋兩個步驟。

java基礎學習(一):java語言概述與開發環境

  Java語言裡負責解釋執行位元組碼檔案的是java虛拟機,即JVM(Java Virtual Machine).JVM是可運作Java位元組碼檔案的虛拟計算機。JVM是Java程式跨平台的關鍵部分,隻要為不同平台實作了相應的虛拟機,編譯後的Java位元組碼就可以在平台上運作。

  JVM的作用作用我覺得很像一個轉接頭,每個接着電腦的接口都是一樣的,但是另一邊的接口是适應着我們手機或者U盤的,也就是說,JVM是一個轉接口,将.clss檔案通過相同的接口解釋,然後再通過适應的不同接口輸出,這樣的話,我們每個平台都能夠很好地使用。

 Oracle 公司制定的Java虛拟機規範在技術上規定了JVM的統一标準,具體定義了JVM的如下細節:

  1. 指令集
  2. 寄存器
  3. 類檔案的格式
  4. 垃圾回收堆
  5. 存儲區

1.2 開發Java的準備

1.2.1 了解JDK

  JDK的全稱是Java SE Development Kit,即Java标準版開發包,是Oracle提供的一套用于開發Java應用程式的開發包,它提供編譯、運作Java程式所需的各種工具和資源,包括Java編譯器,Java運作時環境,以及常見的Java類庫等。

  Java運作時環境,它的全稱是Java Runtime Environment,是以也被稱為JRE,它是運作Java程式的必需條件。

  那麼問題就來了,不是說要JVM才是運作Java的虛拟機碼,那為什麼安裝JRE?事情是這樣的,JRE包含着JVM。因為單單一個核心虛拟機并不足以運作Java位元組碼,還需要很多其他東西。

  這裡我說一下三個的關系:

J V M < J R E < J D K JVM < JRE < JDK JVM<JRE<JDK

  Oracle 把Java分成 Java SE、 Java EE和Java Me 三個部分,而且為Java SE 和 Java EE 分别提供了JDK和Java EE SDK(Software Development Kit) 兩個開發包,如果讀者隻需要學習Java SE 的程式設計知識,則可以下載下傳标準的JDK;如果讀者學完Java SE之後,還需要繼續學習Java EE 相關内容,也可以選擇下載下傳Java EE SDK。

1.2.2 安裝JDK

這裡安裝JDK 我就不寫了。

安裝完後,可以在JDK安裝路徑下看到如下的檔案路徑。

(1)bin:該路徑下存放了JDK的各種工具指令,常用的javac、java等指令就放在該路徑下。

(2)conf:該路徑下存放了JDK的相關配置檔案

(3)include:存放一些平台特定的頭檔案

(4)jmods:該目錄下存放了JDK的各種子產品

(5)legal:該目錄下包含了JDK各子產品的授權文檔

(6)lib:該路徑下存放的是JDK工具的一些補充JAR包

(7)README和COPYRIGHT等說明文檔

1.2.3 設定PATH環境變量

編譯Java程式必須經過兩個步驟:

  1. 将源檔案編譯成位元組碼
  2. 解釋執行平台無關的位元組碼程式

    上面這兩個步驟分别需要使用java和javac兩個指令。這也就是為什麼我們要将這兩個變量存入環境變量中。

這裡解釋一下使用者變量和系統變量的差別?

  使用者變量和系統變量并沒有太大的差别,隻是使用者變量隻對目前使用者有效,而系統變量對所有使用者有效。為了減少自己所做的修改對其他人的影響,故設定使用者變量避免英雄其他人。對于目前使用者而言,設定使用者變量和系統變量的效果大緻相同,隻是系統變量的路徑排在使用者變量的路徑之前。這可能出現一種情況:如果Path系統變量的路徑裡包含樂java指令,而PATH使用者變量的路徑裡也包含了java指令,則有限執行Path系統變量路徑裡包含的java指令。

1.3 編寫程式

  感覺編寫大程式的話,最好還是用IDE工具,但是小程式的話,可以使用記事本編寫,但是最好不要使用寫字闆和World等工具,因為這些文檔中會包含一些隐藏的格式化字元,這些隐藏字元會導緻程式無法正常編譯,運作。

(1) 第一步:編寫Java代碼

  我們在記事本中寫下下面代碼:

public class HelloWorld
{
	public static void main(String[] args)
	{
		System.out.println("Hello World!");
	}
}
           

然後儲存成為HelloWorld.java字尾即可。

(2)第二步:編譯該Java源檔案生成位元組碼

  編譯Java程式需要使用javac指令,因為前面已經把javac指令所在的路徑添加到了系統的PATH環境變量中,是以可以直接使用javac指令來便宜java程式了。

  剛開始學習,就先掌握javac指令的如下用法:

javac -d destdir srcFile
           

  在上面的指令中,-d destdir是javac指令的選項,用以指定編譯生成的位元組碼檔案的存放路徑,destdir隻需是本地磁盤上的一個有效路徑即可;而srcFile是Java源檔案所在的位置,這個位置既可以是絕對路徑,也可以是相對路徑。

  通常,總是将生成的位元組碼檔案放在目前路徑下,目前路徑可以用點(.)來表示。在指令行視窗進入HelloWorld.java檔案所在路徑,在該路徑下輸入如下指令:

javac -d . HelloWorld.java
           

  運作該指令後,在該路徑下生成一個HelloWorld.class檔案

(3)運作Java程式

  運作Java程式使用java指令,啟動指令行視窗,進行HelloWorld.class所在的位置,在指令行視窗輸入:

java java 類名
           

  java指令後面的參數是Java類,而不是位元組碼檔案的檔案名,也不是Java源檔案名。

  通過指令行視窗進入HelloWorld.class所在的路徑,輸入下面指令:

java Java類名
           

運作上面指令,将看到如下輸出:

這樣我們就簡簡單單運作了一個最簡單的程式了。

1.3.1 根據CLASSPATH環境變量定位類

  CLASSPATH環境變量的作用是什麼呢?當使用“java Java類名”指令來運作java程式的時,JRE會到哪個地方去搜尋這個類呢?是以,在1.4以前的版本,JDK沒有自動搜尋目前路徑下的功能,是以需要自己手動配置環境。但1.5以後都沒有這個問題。

  如果想在運作Java程式時臨時指定JRE搜尋Java類的路徑,則可以使用-classpath選項(或用-cp選項)按照下面格式運作java指令:

java -classpath dir1;dir2;dir3...;dirN Java類
           

  -classpath 選項的值可以是一系列的路徑,多個路徑之間Window平台上以分号(;)隔開

  如果在運作Java程式時指定了-classpath選項的值,JRE将嚴格按-classpath選項所制定的路徑來搜尋Java類,即不會再目前路徑下搜尋Java類,CLASSPATH環境變量所指定的搜尋路徑也不再有效。

  如果想使CLASSPATH環境變量指定的搜尋路徑有效,而且還會在目前路徑下搜尋Java類,則可以按如下格式來運作Java程式:

java -classpath %CLASSPATH%;.;dir1;dir2;dir3...,dirN Java 類
           

上面指令通過%CLASSPATH%來引用CLASSPATH環境變量的值,并在-classpath選項的值裡添加了一個點,強制JRE在目前路徑下搜尋Java類。

1.4 Java程式的基本規則

1.4.1 Java程式的組織形式

  Java程式是一種純粹的面向對象的程式設計語言,隐藏Java程式必須以類(class)的形式存在,類(class)是Java程式的最小程式機關。

  上面的HelloWorld.java 程式是一個簡單的程式,但還不是最簡單的java程式,最簡單的Java程式是隻包含一個空類定義的程式。

class Test 
{
}
           

這個程式是可以編譯的,但是進行運作的時候會出錯,就是會出現找不到public static void main(String[] args)這個類的庫。因為如果某一個類要能被解釋器直接解釋運作,這個類就必須包含main方法,main方法寫法是固定的。

1.4.2 Java源檔案的命名規則

Java程式源檔案的命名不是随意的,Java檔案的命名必須滿足如下規則:

(1)Java程式源檔案的擴充名必須是.java,不能是其他檔案擴充名

(2)在通常情況下,Java程式源檔案的主檔案可以是任意的。但是有一種情況例外:如果Java程式源代碼裡面定義了一個public類,則該源檔案的主檔案名必須與該public類的類名相同。

  由于Java程式源檔案的檔案名必須與public類的類名相同,是以,一個Java源檔案裡最多隻能定義一個public類。(用簡單的話來講:就是如果你的.class檔案裡面寫了public類,那麼你的這個.class檔案名就一定要和這個public類的名字一樣)

  雖然Java源檔案裡沒有包含public類定義時,這個源檔案的檔案名可以随便定義的,但是一般都讓Java源檔案的主檔案名與類名相同。一般都有下面建議:

(1)一個Java源檔案隻定義一個類,不同的類使用不同的源檔案定義。

(2)讓Java源檔案的主檔案名與該源檔案中定義的public類同名。

1.5 Java9的GI垃圾回收器

C語言和C++語言都屬于顯式進行垃圾回收。顯式垃圾回收有兩個缺點:

(1)程式忘記及時收回無用記憶體,進而導緻記憶體洩漏,降低系統性能。

(2)程式錯誤地回收程式核心庫的記憶體,進而導緻程式崩潰。

  與C/C++程式不同,Java語言不需要程式員直接控制記憶體回收,Java程式的記憶體配置設定和回收都是由JRE在背景自動進行的。JRE會負責回收那些不再使用的記憶體,這種機制被稱為垃圾回收(Garbage Collection,GC)。通常JRE會提供一個背景線程來進行檢測和控制,一般都是在CPU空閑或記憶體不足時自動進行垃圾回收,而程式員無法精确控制垃圾回收的時間和順序。

  Java的堆記憶體是一個運作時資料區,用以儲存類的執行個體(對象),Java虛拟機的堆記憶體中存儲着正在運作的應用程式所建立的所有對象,這些對象不需要程式通過代碼來顯式釋放。一般來說,堆記憶體的回收由垃圾回收器來負責,所有的JVM實作都有一個由垃圾回收器管理的堆記憶體。垃圾回收是一種動态存儲管理技術,它自動釋放不在被程式引用的對象,按照特定的垃圾回收算法來實作記憶體資源的自動回收功能。

  垃圾回收能自動釋放記憶體空間,減輕程式設計負擔。這使Java虛拟機具有兩個顯著的優點:

(1)垃圾回收機制可以很好地提高程式設計效率。在沒有垃圾回收機制時,可能要花許多時間來解決一個難懂的存儲器問題。在用Java語言程式設計時,依靠垃圾回收機制可以大大縮短時間。

(2)垃圾回收機制保護程式的完整性,垃圾回收是Java語言安全性政策的一個重要部分。

  垃圾回收的一個潛在缺點是它的開銷影響程式性能。Java虛拟機必須跟蹤程式中有用的對象,才可以确定哪些對象是無用的對象,并最終釋放這些無用的對象。這個過程需要花費處理器的時間。其次是垃圾回收算法的不完備性,早先采用的某些垃圾回收算法就不能保證100%收集到所有的廢棄記憶體。當然,随着垃圾回收算法的改進,這些都不是問題。

  簡單說就是:發現無用對象;回收被無用對象占用的記憶體空間,使該空間可被程式再次使用。

垃圾回收具有如下幾個特點:

  • 垃圾回收器的工作目标是回收無用對象的記憶體空間,這些記憶體空間都是 JVM 堆記憶體裡的記憶體空間,垃圾回收器隻能回收記憶體資源,對其他實體資源,如資料庫連接配接、磁盤 I/O 等資源則無能

    為力。

  • 為了更快地讓垃圾回收器回收那些不再使用的對象,可以将該對象的引用變量設定為 null ,通

    過這種方式暗示垃圾回收器可以回收該對象。

  • 垃圾回收發生的不可預知性 由于不同 NM 采用了不同的垃圾回收機制和不同的垃圾回收算法,是以它有可能是定時發生的,有可能是當 CPU 空閑時發生的,也有可能和原始的垃圾回收樣,等到記憶體消耗出現極限時發生,這和垃圾回收實作機制的選擇及具體的設定都有關系。雖然程式員可以通過調用 Runtime 對象的 gc() 和System.gc()等方法來建議系統進行垃圾回收,但這種調用僅僅是建議,依然不能精确控制垃圾回收機制的執行。
  • 垃圾回收的精确性主要包括兩個方面: 是垃圾回收機制能夠精确地标記活着的對象; 是垃圾回收器能夠精确地定位對象之間的引用關系。前者是完全回收所有廢棄對象的前提,否則就可能造成記憶體洩漏;而後者則是實作歸井和複制等算法的必要條件,通過這種引用關系,可以保證所有象都能被可靠地回收,所有對象都能被重新配置設定,進而有效地減少記憶體碎片的産生。
  • 現在的 JVM 有多種不同的垃圾回收實作 每種回收機制因其算法差異可能表現各異,有的當垃圾回收開始時就停止應用程式的運作,有的當垃圾回收運作時 許應用程式的線程運作,還有的在同 時間允許垃圾回收多線程運作。

反正記了這麼多,最重要的一點是:對于不再需要的對象,不要引用它們。

1.6 何時開始使用IDE工具

  對于Java語言的初學者,這裡給出個忠告;不要使用任何IDE工具來學習Java程式設計,Window用記事本,Linux使用Vim。

  結束第一章!

下一篇: 上傳到