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虛擬機,即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字節碼,還需要很多其他東西。
  這裏我說一下三個的關係:
JVM<JRE<JDKJVM < 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!");
	}
}

然後保存成爲.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類名

運行上面命令,將看到如下輸出:

Hello World!

這樣我們就簡簡單單運行了一個最簡單的程序了。

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。

  結束第一章!

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