主頁 > 後端開發 > Java基礎語法(十)—— 認識例外

Java基礎語法(十)—— 認識例外

2021-06-10 07:35:55 後端開發

文章目錄

  • Java基礎語法(十)—— 認識例外
  • 一、初識例外
  • 1.算數例外
  • 2.陣列下標越界例外
  • 3.空指標例外
  • 4.例外的處理方式
  • 5.例外的好處
  • 二、例外的基本語法
  • 1.基本格式
  • 2. 是否處理例外對程式的影響
  • 3.用 try ... catch 需要注意的問題
  • 4.關于例外的處理方式
  • 5.finally 的使用
  • 6.例外處理流程
  • 7.拋出例外
    • (1)throw 的使用
    • (2)宣告例外
    • (3)小結
  • 三、Java例外體系
  • 四、自定義例外類
  • 完!


Java基礎語法(十)—— 認識例外


接上篇博客 Java基礎語法(九)——String 類


本次內容介紹大綱


在這里插入圖片描述

一、初識例外


??經常有同學看到例外來問了,例外到底是什么? 而在我們之前的學習中,我們其實已經接觸到了Java當中的例外,


1.算數例外


??首先我們遇到的第一個例外是我們在講除號運算子時遇到的——算數例外,


見以下代碼

在這里插入圖片描述


我們在分子的位置出現了0,來運行以上代碼,

運行結果:

在這里插入圖片描述

2.陣列下標越界例外


在陣列篇我們也提到了陣列越界的問題


我們來看以下代碼:


在這里插入圖片描述

運行時結果:


在這里插入圖片描述

查看例外的資訊

在這里插入圖片描述

3.空指標例外


空指標例外也在之前的學習中經常出現


看以下代碼


在這里插入圖片描述


??我們將 array 陣列置為 null ,之后再去訪問這個陣列,就出現了空指標例外,


運行結果:

在這里插入圖片描述


??這些例外都是需要我們在平時所積累出來的,

??所謂例外指的就是程式在 運行時 出現錯誤時通知呼叫者的一種機制.


關鍵字 “運行時”

??有些錯誤是這樣的, 例如將 System.out.println 拼寫錯了, 寫成了 system.out.println. 此時編譯程序中就會出錯, 這是 “編譯期” 出錯.

??而運行時指的是程式已經編譯通過得到 class 檔案了, 再由 JVM 執行程序中出現的錯誤.


4.例外的處理方式


??例外的種類有很多, 不同種類的例外具有不同的含義, 也有不同的處理方式.(在此了解即可)


防御式編程


??錯誤在代碼中是客觀存在的. 因此我們要讓程式出現問題的時候及時通知程式猿. 我們有兩種主要的方式


LBYL: Look Before You Leap.
在操作之前就做充分的檢查.

EAFP: It’s Easier to Ask Forgiveness than Permission.
“事后獲取原諒比事前獲取許可更容易”. 也就是先操作, 遇到問題再處理.


其實很好理解,打一個非常形象的比喻來理解啊:


比如說有一個你非常喜歡的女生,你想要去拉她的手,那么有幾種方式呢?

第一種方式 LBYL:問一下:我能拉你的手嗎?


這就是操作之前仔細檢查,


第二種方式 EAFP:直接先把手拉上,她要是甩開了再說其他的,要是沒拒絕就拉著唄,


這就是”事后獲取原諒比事前獲取許可更容易“. 也就是先操作, 遇到問題再處理.


了解即可,不用特別去記憶,


5.例外的好處


我們看一下,上述的兩種風格在處理代碼時究竟是怎樣的呢?

我們先給一個特定的場景啊,處理王者榮耀游戲開局時的例外代碼


LBYL 風格的代碼(不使用例外)
在這里插入圖片描述


??代碼的每一步執行完都要進行檢查,確認正確才能進行下一步,這就是在操作之前做檢查,


EAFP 風格的代碼
在這里插入圖片描述
在這里我們能體會到Java 風格的代碼例外處理


在這里插入圖片描述


??對比兩種不同風格的代碼, 我們可以發現, 使用第一種方式, 正常流程和錯誤處理流程代碼混在一起, 代碼整體顯的比較混亂. 而第二種方式正常流程和錯誤流程是分離開的, 更容易理解代碼.


二、例外的基本語法


??接下來,我們就正式開始了 Java當中 處理例外的 基本語法講解了,


1.基本格式


Java當中 處理例外的基本格式


在這里插入圖片描述


2. 是否處理例外對程式的影響


我們來看一組代碼:


在這里插入圖片描述


??這組代碼中,在代碼執行的第二步中,我們存在著陣列越界例外,那么第三步的 “hello” 是否會列印呢?


我們運行程式,看結果

在這里插入圖片描述


??“hello” 并沒有列印,那么這是為什么呢?此時程式出現例外了,而當程式出現例外時,那么代碼將不會被執行,


??那么我們還是想執行這個“hello”,那么我們該怎么辦呢?


我們就將代碼寫成以下格式的代碼:

在這里插入圖片描述
運行結果;

在這里插入圖片描述

??hello 也成功進行了列印,也就是說,在這種方式下,代碼拋出例外,捕獲例外之后,代碼將繼續向后執行,


??那么又有同學說了,我們定義的那個 e 沒有用到啊,我們再來看 e 的用處


在這里插入圖片描述
e.printStackTrace — 列印出現例外堆疊的追蹤

我們來看這時程式運行結果

在這里插入圖片描述


??這時就把出現例外的堆疊的位置列印出來了,這就是 e 的一個作用吧


??那么又有同學來問了,為什么之前的 “hello”無法列印出來,之后的try…catch 捕捉例外之后能夠列印出來呢?


在這里插入圖片描述

3.用 try … catch 需要注意的問題


1.??在 catch 塊中,一定要捕獲相對應的例外,如果程式拋出的例外在catch 塊當中,不能被捕獲,那么就會交給 JVM 處理,


看以下代碼:

在這里插入圖片描述


??在catch 塊當中并沒有捕獲到 陣列越界例外,我們來看一下運行結果,

在這里插入圖片描述

直接交給 JVM 處理,程式終止,不在向下執行,


2.可以通過catch 捕獲多個例外


我們可以在 try之后 跟上多個 catch 來捕獲例外,如以下代碼:

在這里插入圖片描述

運行程式結果如下:

在這里插入圖片描述


??我們知道,所有的例外都繼承于Exception,那么有人問了,我們可以直接捕獲一個Exception的例外嗎?


我們來試一下,


??我們知道捕捉例外的順序是按照代碼書寫的順序執行的,大家看一下這段代碼

在這里插入圖片描述


當Exception 這個父類例外放在開頭,那么下面的捕捉例外則進行報錯,


??如果這樣寫,那么Exception 后面所有的例外都失效了,為什么呢,因為不管 try {} 里面是什么例外,都會在Exception 這一步進行捕獲到,后面的捕獲例外自然失效了,

??所以當我們在前面寫了 Exception 這個捕獲例外時,后面就不要在進行捕獲其他例外了,


??那么又有同學說了,我們為了省事,那么我們以后都捕獲 Exception 這個 例外不就好了?


??當然不行,在這種情況下,我們不能區分我們捕獲到的是什么例外,所以,不建議大家直接捕獲到一個 Exception 的例外,

3.??不建議大家直接捕獲一個 Exception 的例外


??有些同學想要省事,想要將兩個例外合并成一條進行捕捉,我們只需要將兩個例外用 | 進行連接即可,


給個示例:

在這里插入圖片描述


看一下運行結果:

在這里插入圖片描述

成功運行,


總結


1.??在 catch 塊中,一定要捕獲相對應的例外,如果程式拋出的例外在catch 塊當中,不能被捕獲,那么就會交給 JVM 處理,

2.??可以通過catch 捕獲多個例外

3.??不建議大家直接捕獲一個 Exception 的例外

4.??可以用 | 同時處理兩個例外,如上例,


4.關于例外的處理方式


例外的種類有很多, 我們要根據不同的業務場景來決定.


對于比較嚴重的問題(例如和算錢相關的場景), 應該讓程式直接崩潰, 防止造成更嚴重的后果

對于不太嚴重的問題(大多數場景), 可以記錄錯誤日志, 并通過監控報警程式及時通知程式猿

對于可能會恢復的問題(和網路相關的場景), 可以嘗試進行重試.

??在我們當前的代碼中采取的是經過簡化的第二種方式. 我們記錄的錯誤日志是出現例外的方法呼叫資訊, 能很快速的讓我們找到出現例外的位置. 以后在實際作業中我們會采取更完備的方式來記錄例外資訊.


關于 “呼叫堆疊”


??方法之間是存在相互呼叫關系的, 這種呼叫關系我們可以用 “呼叫堆疊” 來描述. 在 JVM 中有一塊記憶體空間稱為 “虛擬機堆疊” 專門存盤方法之間的呼叫關系. 當代碼中出現例外的時候, 我們就可以使用 e.printStackTrace(); 的方式查看出現例外代碼的呼叫堆疊.


5.finally 的使用


我們再來看一下例外基礎語法的學習

在這里插入圖片描述


我們看到了try…catch 之后還可以跟著 finally

那我們來說一下 finally 的特性


??不管 這個代碼 是否拋出例外,finally 的 內容都會被執行,所以 finally 經常來做一些善后的內容,比如:關閉資源


我們來看一下這一組代碼

在這里插入圖片描述

考一下大家,這組代碼執行的結果是什么呢?

運行結果如下:

在這里插入圖片描述

列印結果為2,這是為什么呢?

首先我們需要明確的一點是,finally 的內容一定會被執行,


我們分析一下:

??在try 塊當中,在列印 array[4]時出現例外,后面的return 陳述句就不再執行了,所以最后執行 finally 塊,回傳2.


我們再來看一個代碼示例:

在這里插入圖片描述

這組代碼執行的結果是什么呢?


運行結果:

在這里插入圖片描述


最后回傳了2.


這又再次明確了一點:


finally 的內容是一定會被執行的


finally 的使用 總結


1.finally 塊當中的代碼終究會被執行的

2 .不建議在 finally 當中出現 return 陳述句.


6.例外處理流程


在這里插入圖片描述


??好了,到現在,我們算是講清楚了 try…catch…finally 及例外處理的流程等問題,那么大家以后在寫代碼的程序中,一定要記得去使用 try…catch,不能一味的交給 JVM 來處理它,好了我們開始下一塊內容——拋出例外,


7.拋出例外


??除了 Java 內置的類會拋出一些例外之外, 程式猿也可以手動拋出某個例外. 使用 throw 關鍵字完成這個操作,


??throw 一般拋出一個你想要拋出的例外(或者自定義的例外)


(1)throw 的使用


我們來看代碼示例:

在這里插入圖片描述


??我們用 throw new 了一個算數例外,為什么要 new 呢? 因為算數例外本身也是一個類,也要實體化,


我們來看運行時結果;


在這里插入圖片描述


??成功的拋出例外了,但是這樣寫有一個不好的地方,我們拋出了一個例外但是呢,這個例外我們只是拋出了但是并未處理,所以最后程式出現例外后交給JVM處理,程式最后終止,


(2)宣告例外


??對于我們呼叫devide 方法的人來說啊,如果 devide 方法的內容很多,我們就看不出 devide 會拋出一個例外,那么為了讓呼叫devide 方法的人知道,我們呼叫這個方法會拋出這個例外,一般情況下,我們會給這個方法進行宣告例外,那么怎么宣告呢?


通過throws 宣告這個方法會拋出一個例外


下面我們來看代碼示例:

在這里插入圖片描述

??方法呼叫者知道了呼叫該方法可能會拋出 算數例外,就用上了 try…catch 來捕獲例外,


運行結果:

在這里插入圖片描述

(3)小結

在這里插入圖片描述

三、Java例外體系


那么例外到底有多少種?要了解這個問題,我們就需要知道Java的例外體系了,


在這里插入圖片描述


上圖并沒有將所有的例外都列舉出來,只是大概演示一下,


在Java當中,我們所看到的例外,其實也就是對應著一個類,


??由上圖中我們可以看到,整個Java 例外體系 都是繼承于頂層類 Throwable,那么 Throwable 就是所有例外、錯誤的父類,


對于Throwable 來說,直接繼承這個類的有兩個子類,


Error ( 錯誤 ) 和 Exception(例外).


我們來看一下 jdk_api 幫助手冊中對 Throwable 的解釋

在這里插入圖片描述


我們這篇講的是 例外,怎么又出現一個 錯誤Error呢?

我們也來認識以下Error

比如說我們寫一個代碼:


在這里插入圖片描述
運行之后出現以下結果:

在這里插入圖片描述
我們來對比一下:

在這里插入圖片描述
例外是以Exception 結尾的,而錯誤是以 Error 結尾的,

對于Error 來說——這種錯誤一定得由程式員自己解決,

而對于Exception 來說——例外時可以由程式自己解決的,

而例外又有以下劃分

在這里插入圖片描述
??運行時例外 Runtime Exception就是我們上面提到的 算數例外、陣列越界例外、型別轉換例外等等,那么就有同學問了?


什么是運行時例外?

運行時例外就是在程式運行的時候拋出的例外

什么是編譯時例外?

編譯時例外就是在程式編譯時拋出的例外


如果一段代碼可能拋出 受查例外, 那么必須顯式進行處理.


顯式處理的方式有兩種:


a) 使用 try catch 包裹起來
b) 在方法上加上例外說明, 相當于將處理動作交給上級呼叫者

別忘了 IDEA 神奇的 alt + enter, 能夠快速修正代碼.

小結

在這里插入圖片描述


四、自定義例外類


??Java 中雖然已經內置了豐富的例外類, 但是我們實際場景中可能還有一些情況需要我們對例外類進行擴展, 創建符合我們實際情況的例外.


我們來實作一個簡單的自定義的例外類


??首先 我們要自定義一個例外類 同時繼承一個父類例外

在這里插入圖片描述
那么這個我們自定義的例外怎么用呢?

下面我們來看

在這里插入圖片描述
運行結果:

在這里插入圖片描述

這就是我們自定義例外的使用,

我們再來一個代碼示例

下面我們給一個真實的業務場景


例如, 我們實作一個用戶登陸功能.


在這里插入圖片描述


??此時我們在處理用戶名密碼錯誤的時候可能就需要拋出兩種例外. 我們可以基于已有的例外類進行擴展(繼承), 創建和我們業務相關的例外類.


在這里插入圖片描述


此時我們的 login 代碼可以改成


在這里插入圖片描述


自定義類的注意事項


1.自定義例外通常會繼承自 Exception 或者 RuntimeException

2.繼承自 Exception 的例外默認是受查例外

3.繼承自 RuntimeException 的例外默認是非受查例外.



??好了今天的知識就分享到這里,希望大家多多練習,熟練掌握,感謝大家的欣賞與關注!!




謝謝欣賞!




完!

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/286380.html

標籤:java

上一篇:大學四年自學Java編程,總結了這四條寶貴經驗!

下一篇:漫畫:什么是JVM的垃圾回收?

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more