綜述:
Java學習圖譜:
常見dos命令:
操作案例:
Java語言的特點:
面向對象
兩個基本概念:類、對象
三個基本特性:封裝、繼承、多態
健壯性、可繼承性
write once,run anywhere !
java兩種核心機制:Java虛擬機、垃圾回收機制
jdk安裝及環境變量配置:
配置參考:
https://www.runoob.com/java/java-environment-setup.html
其他:
在一個Java源文件中可以聲明多個class,但是只能有一個類聲明為public,而且要求聲明為public的類名必須與文件名同名
編譯的過程:編譯的過程中會生成字節碼文件,編譯的文件中有多少個類就有多少個字節碼文件
標識符:
凡是可以自己命名的地方都叫標識符。
Java語言嚴格區分大小寫
變量:
整數類型:
聲明long型變量必須以大寫L或者小寫l結尾。
浮點數類型:
char類型:
轉移符號還可用於單引號雙引號等
布爾類型:
自動類型轉換:
在編程過程中,定義long型變量時未加L,默認為int類型,然后通過自動類型轉換為long型
定義float型變量時必加f
字符串類型:
強制類型轉換:
將容量大的數據類型轉換為容量小的數據類型。
整型常量默認為int型
浮點數常量默認為double型
進制:
二進制:0b開頭
八進制:0開頭
十六進制:0x開頭
運算符:
為什么說最高位右移補零或補一,最高位是符號位
三元運算符:
運算符優先級:
break與continue:
break語句用於終止某個語句塊;
continue用於跳過所在循環語句塊的一次執行,繼續下一次循環;
return:當一個語句執行到return語句時,return直接結束整個方法;
scanner輸入
具體可參考Javadoc : scanner
數組:
多個相同類型數據按一定順序排列的集合。
聲明:
type var[] 或 type[] var
初始化:
數組長度:arr.length
數組元素默認初始值:
內存的簡化結構:
實例分析:
1.首先在堆中創建了一個新的連續空間(new) ,默認初始值為0,0,0
2.初始化f賦值為1,2,3
3.連續空間地址(首元素地址)為0x34ab,棧中arr(位於main方法中,為局部變量)指向該地址。
4.再在堆中創建了一個新的連續空間(new) ,默認初始值為null,null,null,null
5.連續空間地址(首元素地址)為0x12ab,棧中arr1(位於main方法中,為局部變量)指向該地址
6.設置數組第二個元素為劉德華
7.設置數組第三個元素為張學友
8.再在堆中創建了一個新的連續空間(new) ,默認初始值為null,null,null,首地址為0x5566
9.arr1指向地址0x5566
10.不確定的某一時間地址為0x12ab的連續空間被回收
多維數組:
上面注意的意思是int[] y[] 是二維數組
二維數組內存分析:
arrays常見工具類:
面向對象:
對象的內存分析:
屬性:
成員變量與局部變量:
方法:
stu.score=(int) (Math.random() *(m-n+1)) //n~m之間的隨機數
方法重載:
可變個數的形參:
封裝和隱藏:
構造器:
各種賦值方式的先后順序:
拓展:UML圖:
this關鍵字的使用:
注意:
繼承:
注意:Java只支持單繼承和多層繼承
重寫:
四種訪問修飾符:
關鍵字super:
調用父類構造器:
多態性: 父類的引用指向子類的對象
對象的多態性只適用於方法,不適用於屬性(編譯和運行都看左邊)
instanceof: 用於判斷向下轉型時避免出現classCastException
Casting:強制類型轉換
object類:
object類是所有類的父類
object類只聲明了一個空參構造器
== 與equals:
==:運算符
1.可以使用在基本數據類型變量中和引用數據類型變量中
2.在基本數據類型中比較兩個變量保存的數據是否相等(不一定要數據類型相同)
3.比較的是引用數據類型即比較兩個對象的地址值是否相同,即兩個引用是否指向同一個對象實體
equals():方法
1.是一個方法而非運算符,只能適用於引用數據類型
2.object類中定義的equals方法同==,比較對象的地址值是否相同
3.像String、Date、File、包裝類都重寫了object類中的equals()方法,重寫以后比較的不是引用地址是否相同,而是比較兩個對象的“實體內容”是否相同。
4.通常情況下我們自定義的equals()類希望達到的是比較“實體內容''的效果,我們就需要對object類中的equals()方法進行重寫。
toString方法:
包裝類(Wrapper):
自動裝箱與自動拆箱:
三者間的轉換:
關鍵字static:
靜態的,可以用來修飾屬性、方法、代碼塊、內部類
使用static修飾屬性,靜態變量(類變量) :創建了類的多個對象,多個對象共享同一個靜態變量,當通過某一對象修改靜態變量時,其他對象的靜態變量也變為修改過后的。
(非靜態變量(實例屬性)):創建了類的多個對象時,每個對象都獨立的擁有一套類的非靜態屬性,每個對象的非靜態屬性相互獨立。
說明:
1.靜態變量隨着類的加載而加載
2.靜態變量的加載要早於對象的創建
3.由於類只會加載一次,靜態變量在內存中也只會存在一份,存在方法區的靜態域中
-
類變量 實例變量
類 yes no
對象 yes no
靜態方法:
隨着類的加載而加載,調用可參考如上
靜態方法中只能調用靜態的方法和屬性,非靜態方法可以調用非靜態屬性和方法也可以調用靜態屬性和方法。(原因:生命周期問題)
在靜態的方法內不能使用this關鍵字、super關鍵字
單例設計模式:
懶漢式與餓漢式:懶漢式啥時候用是時候造對象,餓漢式(飢渴)早早就造了對象。
代碼塊:
final修飾屬性可以考慮的位置: 1.顯式初始化 2.代碼塊中初始化 3.構造器中初始化
final修飾局部變量:尤其是使用final修飾形參時,表明此形參是一個常量,當我們調用此方法時,給常量形參賦一個實參,一旦調用以后就只能在此方法體內使用此形參,但不能進行重新賦值。
抽象類:
接口:
接口與接口之間可以多繼承。
創建接口匿名實現類的四種實現方法:
package com.atguigu.java1;
/*
* 接口的使用
* 1.接口使用上也滿足多態性
* 2.接口,實際上就是定義了一種規范
* 3.開發中,體會面向接口編程!
*
*/
public class USBTest {
public static void main(String[] args) {
Computer com = new Computer();
//1.創建了接口的非匿名實現類的非匿名對象
Flash flash = new Flash();
com.transferData(flash);
//2. 創建了接口的非匿名實現類的匿名對象
com.transferData(new Printer());
//3. 創建了接口的匿名實現類的非匿名對象
USB phone = new USB(){
@Override
public void start() {
System.out.println("手機開始工作");
}
@Override
public void stop() {
System.out.println("手機結束工作");
}
};
com.transferData(phone);
//4. 創建了接口的匿名實現類的匿名對象
com.transferData(new USB(){
@Override
public void start() {
System.out.println("mp3開始工作");
}
@Override
public void stop() {
System.out.println("mp3結束工作");
}
});
}
}
class Computer{
public void transferData(USB usb){//USB usb = new Flash();
usb.start();
System.out.println("具體傳輸數據的細節");
usb.stop();
}
}
interface USB{
//常量:定義了長、寬、最大最小的傳輸速度等
void start();
void stop();
}
class Flash implements USB{
@Override
public void start() {
System.out.println("U盤開啟工作");
}
@Override
public void stop() {
System.out.println("U盤結束工作");
}
}
class Printer implements USB{
@Override
public void start() {
System.out.println("打印機開啟工作");
}
@Override
public void stop() {
System.out.println("打印機結束工作");
}
}
代理模式:
public class StaticProxyTest {
public static void main(String[] args) {
Star s = new Proxy(new RealStar());
s.confer();
s.signContract();
s.bookTicket();
s.sing();
s.collectMoney();
}
}
interface Star {
void confer();// 面談
void signContract();// 簽合同
void bookTicket();// 訂票
void sing();// 唱歌
void collectMoney();// 收錢
}
//被代理類
class RealStar implements Star {
public void confer() {
}
public void signContract() {
}
public void bookTicket() {
}
public void sing() {
System.out.println("明星:歌唱~~~");
}
public void collectMoney() {
}
}
class Proxy implements Star {
private Star real;
public Proxy(Star real) {
this.real = real;
}
public void confer() {
System.out.println("經紀人面談");
}
public void signContract() {
System.out.println("經紀人簽合同");
}
public void bookTicket() {
System.out.println("經紀人訂票");
}
public void sing() {
real.sing();
}
public void collectMoney() {
System.out.println("經紀人收錢");
}
}
/*
經紀人面談
經紀人簽合同
經紀人訂票
明星:歌唱~~~
經紀人收錢
*/
面試題:
Java8新特性:
package com.atguigu.java8;
public class SubClassTest {
public static void main(String[] args) {
SubClass s = new SubClass();
// s.method1();
// SubClass.method1();
//知識點1:接口中定義的靜態方法,只能通過接口來調用。
CompareA.method1();
//知識點2:通過實現類的對象,可以調用接口中的默認方法。
//如果實現類重寫了接口中的默認方法,調用時,仍然調用的是重寫以后的方法
s.method2();
//知識點3:如果子類(或實現類)繼承的父類和實現的接口中聲明了同名同參數的默認方法,
//那么子類在沒有重寫此方法的情況下,默認調用的是父類中的同名同參數的方法。-->類優先原則
//知識點4:如果實現類實現了多個接口,而這多個接口中定義了同名同參數的默認方法,
//那么在實現類沒有重寫此方法的情況下,報錯。-->接口沖突。
//這就需要我們必須在實現類中重寫此方法
s.method3();
}
}
class SubClass extends SuperClass implements CompareA,CompareB{
public void method2(){
System.out.println("SubClass:上海");
}
//知識點四,在沒有繼承父類superclass的條件下的接口沖突情況,重寫method3()
public void method3(){
System.out.println("SubClass:深圳");
}
//知識點5:如何在子類(或實現類)的方法中調用父類、接口中被重寫的方法
public void myMethod(){
method3();//調用自己定義的重寫的方法
super.method3();//調用的是父類中聲明的
//調用接口中的默認方法
CompareA.super.method3();
CompareB.super.method3();
}
}
內部類:
成員內部類:
package com.atguigu.java2;
/*
* 類的內部成員之五:內部類
* 1. Java中允許將一個類A聲明在另一個類B中,則類A就是內部類,類B稱為外部類
*
* 2.內部類的分類:成員內部類(靜態、非靜態) vs 局部內部類(方法內、代碼塊內、構造器內)
*
* 3.成員內部類:
* 一方面,作為外部類的成員:
* >調用外部類的結構
* >可以被static修飾
* >可以被4種不同的權限修飾
*
* 另一方面,作為一個類:
* > 類內可以定義屬性、方法、構造器等
* > 可以被final修飾,表示此類不能被繼承。言外之意,不使用final,就可以被繼承
* > 可以被abstract修飾
*
*
* 4.關注如下的3個問題
* 4.1 如何實例化成員內部類的對象
* 4.2 如何在成員內部類中區分調用外部類的結構
* 4.3 開發中局部內部類的使用 見《InnerClassTest1.java》
*
*/
public class InnerClassTest {
public static void main(String[] args) {
//創建Dog實例(靜態的成員內部類):
Person.Dog dog = new Person.Dog();
dog.show();
//創建Bird實例(非靜態的成員內部類):
// Person.Bird bird = new Person.Bird();//錯誤的
Person p = new Person();
Person.Bird bird = p.new Bird();
bird.sing();
System.out.println();
bird.display("黃鸝");
}
}
class Person{
String name = "小明";
int age;
public void eat(){
System.out.println("人:吃飯");
}
//靜態成員內部類
static class Dog{
String name;
int age;
public void show(){
System.out.println("卡拉是條狗");
// eat();
}
}
//非靜態成員內部類
class Bird{
String name = "杜鵑";
public Bird(){
}
public void sing(){
System.out.println("我是一只小小鳥");
Person.this.eat();//調用外部類的非靜態屬性
eat();
System.out.println(age);
}
public void display(String name){
System.out.println(name);//方法的形參
System.out.println(this.name);//內部類的屬性
System.out.println(Person.this.name);//外部類的屬性
}
}
public void method(){
//局部內部類
class AA{
}
}
{
//局部內部類
class BB{
}
}
public Person(){
//局部內部類
class CC{
}
}
}
局部內部類:
package com.atguigu.java2;
public class InnerClassTest1 {
//開發中很少見
public void method(){
//局部內部類
class AA{
}
}
//返回一個實現了Comparable接口的類的對象
public Comparable getComparable(){
//創建一個實現了Comparable接口的類:局部內部類
//方式一:
// class MyComparable implements Comparable{
//
// @Override
// public int compareTo(Object o) {
// return 0;
// }
//
// }
//
// return new MyComparable();
//方式二:
return new Comparable(){
@Override
public int compareTo(Object o) {
return 0;
}
};
}
}
異常處理:
runtime Exception類的異常Java可自行捕獲,IOException必須使用try catch捕獲
package com.atguigu.java1;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.junit.Test;
/*
* 一、異常的處理:抓拋模型
*
* 過程一:"拋":程序在正常執行的過程中,一旦出現異常,就會在異常代碼處生成一個對應異常類的對象。
* 並將此對象拋出。
* 一旦拋出對象以后,其后的代碼就不再執行。
*
* 關於異常對象的產生:① 系統自動生成的異常對象
* ② 手動的生成一個異常對象,並拋出(throw)
*
* 過程二:"抓":可以理解為異常的處理方式:① try-catch-finally ② throws
*
*
* 二、try-catch-finally的使用
*
* try{
* //可能出現異常的代碼
*
* }catch(異常類型1 變量名1){
* //處理異常的方式1
* }catch(異常類型2 變量名2){
* //處理異常的方式2
* }catch(異常類型3 變量名3){
* //處理異常的方式3
* }
* ....
* finally{
* //一定會執行的代碼
* }
*
* 說明:
* 1. finally是可選的。
* 2. 使用try將可能出現異常代碼包裝起來,在執行過程中,一旦出現異常,就會生成一個對應異常類的對象,根據此對象
* 的類型,去catch中進行匹配
* 3. 一旦try中的異常對象匹配到某一個catch時,就進入catch中進行異常的處理。一旦處理完成,就跳出當前的
* try-catch結構(在沒有寫finally的情況)。繼續執行其后的代碼
* 4. catch中的異常類型如果沒有子父類關系,則誰聲明在上,誰聲明在下無所謂。
* catch中的異常類型如果滿足子父類關系,則要求子類一定聲明在父類的上面。否則,報錯
* 5. 常用的異常對象處理的方式: ① String getMessage() ② printStackTrace()
* 6. 在try結構中聲明的變量,再出了try結構以后,就不能再被調用
* 7. try-catch-finally結構可以嵌套
*
* 體會1:使用try-catch-finally處理編譯時異常,是得程序在編譯時就不再報錯,但是運行時仍可能報錯。
* 相當於我們使用try-catch-finally將一個編譯時可能出現的異常,延遲到運行時出現。
*
* 體會2:開發中,由於運行時異常比較常見,所以我們通常就不針對運行時異常編寫try-catch-finally了。
* 針對於編譯時異常,我們說一定要考慮異常的處理。
*/
public class ExceptionTest1 {
@Test
public void test2(){
try{
File file = new File("hello.txt");
FileInputStream fis = new FileInputStream(file);
int data = fis.read();
while(data != -1){
System.out.print((char)data);
data = fis.read();
}
fis.close();
}catch(FileNotFoundException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
}
@Test
public void test1(){
String str = "123";
str = "abc";
int num = 0;
try{//注意:try里面的語句不表現執行,即不會print
num = Integer.parseInt(str);
System.out.println("hello-----1");
}catch(NumberFormatException e){
// System.out.println("出現數值轉換異常了,不要着急....");
//String getMessage():
// System.out.println(e.getMessage());
//printStackTrace():
e.printStackTrace();
}catch(NullPointerException e){
System.out.println("出現空指針異常了,不要着急....");
}catch(Exception e){
System.out.println("出現異常了,不要着急....");
}
System.out.println(num);
System.out.println("hello-----2");
}
}
throws方式:
throws+異常類型寫在方法聲明處,指明此方法執行時可能拋出的異常類型,一旦當方法體執行時,出現異常,任會在異常代碼出生成一個異常類對象,此對象滿足throws后的異常類就會拋出,異常代碼后續的代碼就不再執行。
體會:try-catch-finally:真正的將異常給處理了
throws:沒有處理異常,將異常拋給了方法的調用者
方法重寫的規則:子類重寫的方法異常不大於父類重寫的方法異常
package com.atguigu.java1;
import java.io.FileNotFoundException;
import java.io.IOException;
/*
* 方法重寫的規則之一:
* 子類重寫的方法拋出的異常類型不大於父類被重寫的方法拋出的異常類型
*
*
*/
public class OverrideTest {
public static void main(String[] args) {
OverrideTest test = new OverrideTest();
test.display(new SubClass());
}
public void display(SuperClass s){
try {
s.method();
} catch (IOException e) {
e.printStackTrace();
}
}
}
class SuperClass{
public void method() throws IOException{
}
}
class SubClass extends SuperClass{
public void method()throws FileNotFoundException{
}
}
開發中如何選擇使用try-catch-finally 還是使用throws?
- 3.1 如果父類中被重寫的方法沒有throws方式處理異常,則子類重寫的方法也不能使用throws,意味着如果子類重寫的方法中有異常,必須使用try-catch-finally方式處理。
- 3.2 執行的方法a中,先后又調用了另外的幾個方法,這幾個方法是遞進關系執行的(a執行的方法產生結果x傳遞給方法b使其能夠運行......)。我們建議這幾個方法使用throws的方式進行處理(如果用try catch 異常被捕獲方法能運行,但后續的方法運行結果錯誤,無意義)。而執行的方法a可以考慮使用try-catch-finally方式進行處理。
手動拋出異常:
throw
自定義異常類及拋出:
package com.atguigu.java2;
/*
* 如何自定義異常類?
* 1. 繼承於現有的異常結構:RuntimeException 、Exception
* 2. 提供全局常量:serialVersionUID
* 3. 提供重載的構造器
*
*/
public class MyException extends Exception{
static final long serialVersionUID = -7034897193246939L;
public MyException(){
}
public MyException(String msg){
super(msg);
}
}
package com.atguigu.java2;
public class StudentTest {
public static void main(String[] args) {
try {
Student s = new Student();
s.regist(-1001);
System.out.println(s);
} catch (Exception e) {
// e.printStackTrace();
System.out.println(e.getMessage());
}
}
}
class Student{
private int id;
public void regist(int id) throws Exception {
if(id > 0){
this.id = id;
}else{
// System.out.println("您輸入的數據非法!");
//手動拋出異常對象
// throw new RuntimeException("您輸入的數據非法!");
// throw new Exception("您輸入的數據非法!");
throw new MyException("不能輸入負數");
//錯誤的
// throw new String("不能輸入負數");
}
}
@Override
public String toString() {
return "Student [id=" + id + "]";
}
}
package com.atguigu.exer;
//自定義異常類
public class EcDef extends Exception {
static final long serialVersionUID = -33875164229948L;
public EcDef() {
}
public EcDef(String msg) {
super(msg);
}
}
package com.atguigu.exer;
/*
* 編寫應用程序EcmDef.java,接收命令行的兩個參數,要求不能輸入負數,計算兩數相除。
對數據類型不一致(NumberFormatException)、缺少命令行參數(ArrayIndexOutOfBoundsException、
除0(ArithmeticException)及輸入負數(EcDef 自定義的異常)進行異常處理。
提示:
(1)在主類(EcmDef)中定義異常方法(ecm)完成兩數相除功能。
(2)在main()方法中使用異常處理語句進行異常處理。
(3)在程序中,自定義對應輸入負數的異常類(EcDef)。
(4)運行時接受參數 java EcmDef 20 10 //args[0]=“20” args[1]=“10”
(5)Interger類的static方法parseInt(String s)將s轉換成對應的int值。
如:int a=Interger.parseInt(“314”); //a=314;
*/
public class EcmDef {
public static void main(String[] args) {
try{
int i = Integer.parseInt(args[0]);
int j = Integer.parseInt(args[1]);
int result = ecm(i,j);
System.out.println(result);
}catch(NumberFormatException e){
System.out.println("數據類型不一致");
}catch(ArrayIndexOutOfBoundsException e){
System.out.println("缺少命令行參數");
}catch(ArithmeticException e){
System.out.println("除0");
}catch(EcDef e){
System.out.println(e.getMessage());
}
}
public static int ecm(int i,int j) throws EcDef{
if(i < 0 || j < 0){
throw new EcDef("分子或分母為負數了!");
}
return i / j;
}
}