執行Java程式.
Java程式有兩種方式一種是jar包。一種是class. 執行jar,Java -jar XXX.jar執行的時候,Java.exe調用GetMainClassName函數,該函數先獲得JNIEnv執行個體然後調用Java類Java.util.jar.JarFileJNIEnv中方法getManifest()并從傳回的Manifest對象中取getAttributes("Main-Class")的值即jar包中檔案:META-INF/MANIFEST.MF指定的Main-Class的主類名作為執行的主類。之後main函數會調用Java.c中LoadClass方法裝載該主類(使用JNIEnv執行個體的FindClass)。main函數直接調用Java.c中LoadClass方法裝載該類。假設是執行class方法。main函數直接調用Java.c中LoadClass方法裝載該類。
然後main函數調用JNIEnv執行個體的GetStaticMethodID方法查找裝載的class主類中
“public static void main(String[] args)”方法,并推斷該方法是否為public方法,然後調用JNIEnv執行個體的
CallStaticVoidMethod方法調用該Java類的main方法。
----------------------------------------------------
堆和棧是分别管理 對象和位址值的。非靜态在擷取執行個體的時候須要一個引用,(是以須要new一個對象) 而靜态則不須要
native 是java用來和c/c++ 打交到的,早期java剛剛出生是c/c++橫行的時候,java為了适應當時的格局。是以在jvm中開辟了一塊空間特地來處理c/c++的程式。
這塊區域他叫做native。
而native是用來處理程式和硬體打交到的區域。
棧裡面是存放位址引用,堆裡面的存放的是實體對象。棧的速度快。堆比較慢。
JAVA_HOME
D:\Java\bin
PATH
%JAVA_HOME%;%System%.....
設定暫時的環境變量
set path="u盤上的jre檔案bin檔案的路徑",這樣path的路徑就變為了暫時的了。他的生命周期就在目前窗體。關閉就沒有了。
javac xxx.java
class 檔案不在目前目錄下
-->set classpath f:\xxx\xx\ 這樣子過去,能夠為目前類檔案設定一個暫時的路徑。
& 過程中僅僅要有一邊為假,就為假
| 過程中僅僅要有一邊為真,就為真
&&左邊為false時不參與運算
||左邊為true時不參與運算
位運算。計算機專用,用于操作2進制的運算。
if(){}else if(){}else if(){} else //這個盡管由多個代碼塊組成。可是僅僅有一個會運作。
if 和 switch 建議僅僅使用 switch switch會把選擇答案載入進記憶體,選擇效率會高點。 int byte short char enum string
while(){}
do while(){}不管條件是否滿足,循環體都要運作一次。
(\r \n回車) (\t制表符) (\轉義字元)
辨別符:
wai:for(int i;i<10;i++){
nei:for(int j;j<10;j++){
break wai; //跳出外循環
}
}
重載:方法名同樣。參數個數不同,傳回值類型不同。
數組:同一類型,固定個數的容器。
選擇排序:1 第一個和後面的每個比較,小的放前面。内圈和外圈做比較。2 内圈的起始變量是外圈的第二個。3 來個暫時變量,為2個角标的引用做交換。
冒泡排序:1 相鄰的2個數做比較。大的放後面。
2 内圈變量是外圈長度減一。3 來個暫時變量。為2個角标的引用做交換。
Arrays.sort(arr);//開發專用 ,甯外希爾排序,效率非常高。
二分法查找:1 必須是有序的。
>>>右移動4位,<<<左移動4位 , 在10進制中一個數&15 相當于找到自身。
Integer.toBinatyString(-6); 十--->二進制
Integer.toOctalString(-6); 十--->八進制
Integer.toHexString(-6); 十--->十六進制
二維數組
引用資料類型,在堆裡面,預設初始化值是null。在沒有不論什麼指向之前他就是null。
int arr[][]={{1,2,3},{4,5,6},{7,8,9}};
int sum=0;
for(int i;i<arr.length;i++){
for(int j;j<arr[i].length;j++){
sum+=arr[i][j];
面向對象:
1 面向對象思想是一種符合現實社會中人們對問題思考習慣的思想。
2 把現實社會中複雜的事情簡單化(eg:買電腦)
3 把運作者,變為指揮者(eg:買電腦)
--------------------
3 種引用類型的變量。
1 數組。
2 類。
3 接口。
局部變量和成員變量的差别
1 在類中定義的位置不同
2 在記憶體中的生命周期不同(堆和棧)
3 生命周期不同
4 初始化值不一樣。
匿名對象的使用場景:當對象方法或屬性僅僅有一次調用的時候就用匿名對象。
五片記憶體區域:
1 寄存器。
2 本地方法區[和jni一起用]。
3 棧記憶體。
4 堆記憶體。
5 方法區[資料共享區]。
---------------------------------------------------------
1 封裝:隐藏對象的屬性和實作細節,僅對提供公共的訪問和操作方式。
構造函數:将對象初始化。每個類都有一個預設的構造函數。
this:表示目前對象,位元組碼。
誰調用這個類。this就代表誰。
{} 構造代碼塊。每次建立一個對象都會運作一次。而構造函數僅僅運作一次。
--------------------
static: 和方法一樣。存在方法區中,而方法是在被調用的時候才進棧,被static修飾的就是一直存在方法區中。
---1 被static修飾的,優先于對象存在。
---2 随着類的載入而載入,消失而消失。
---3 被全部成員共享。
---4 靜态僅僅能調用靜态。非靜态能夠調用靜态。
static(類變量(在方法區中))object(執行個體變量(在堆中))
方法預設存儲在方法區中,而當執行的時候才在棧中。
---------------
static 代碼塊(那他和jni有什麼差别呢)
1 随着類的載入而載入,并且僅僅運作一次。
2 優先于主函數運作。
3 給類初始化。
單例模式:為了保證一個project僅僅有一個對象。
eg: 對象也能夠用來封裝資料。
1 懶漢式。
2 餓漢式。
由于static 是随着類的載入而載入的,浪費記憶體。
是以為了避免一定的空間浪費,開發中推薦懶漢式,特别是android
單例中出現的方法。是為了[可控]
--------------------------------------------------------
2 繼承:(單繼承[調用的不确定性],多實作)
1 讓類與類之間産生了關系。
2 對共性進行了抽取(屬性和方法)。
3 子類能夠調用父類的屬性和方法。前提是僅僅能訪問父類中public的。
并且子類中使用的時候不會自己主動提示,可是我們手動寫。
4 在子類的全部構造函數的第一行,預設有一句 super(),他會去調用父類的構造方法。
5 【凡是】子類繼承父類。父類和子類的屬性,都在子類的堆記憶體區其中。是以父類有的,子類就能夠不用寫了。寫了就是記憶體浪費。
特殊情況[android 自己定義控件]例如以下:
6 當子類重寫父類了的方法之後。就會将父類的方法進行屏蔽。以後調用這種方法,都是去運作子類的邏輯,在android自己定義控件中用的比較多。
7 結論:父類的構造函數,既能夠給本類對象初始化,也能夠給子類對象初始化。
------------------
繼承就是不斷的向上抽取。僅僅有在其子類才有特有的功能,什麼時候繼承得看情況。
this能夠代表目前對象。super 代表父類空間。
被private 修飾的不能被子類繼承訪問。
可是子類的堆記憶體中有。
當子父類中出現一摸一樣的方法時。子類會覆寫(重寫)父類的方法。
而且子類的權限要>=父類。
重載是函數名同樣,參數不同。和覆寫不一樣。
static僅僅能覆寫static
在一個類中:當有參構造的出現,預設的無參構造會消失。
繼承會把父類中的所有public的功能所有拿過來。
final
被final 修飾的屬性不能改動、類不能繼承、方法不能重寫。
在開發中常量就能夠用final 來修飾,可是名稱得大寫。
并且在繼承中,假設子類中有,預設是調用子類的,子類沒有才調用父類的。
構造代碼塊:在super()和自己的代碼之間,會調用構造代碼塊。
一個對象在記憶體中産生的過程:
1 将該對象所需的類檔案載入進記憶體。
2 在記憶體中進行空間的方法區的空間配置設定。
3 通過new 在堆中開辟空間。
4 對象中的屬性進行預設初始化。
5 調用與之對象的構造函數進行初始化。
6 通過構造函數的super調用父類中的構造函數初始化。
7 對象中的屬性進行顯示初始化。
8 構造代碼塊初始化。
9 該構造函數内部自己定義内容進行初始化。
抽象:is a [是](多個子類繼承同一個父類)
當你描寫叙述一個事物的時候,沒有足夠的資訊對該事物進行描寫叙述,那麼這個事物相應的類就是一個抽象類。
抽象類不能執行個體化。
抽象類中的方法必須所有重寫。
抽象類中能有自己的特有方法。(接口不能)
抽象類必需要被繼承。
子類能繼承一切非 private 的方法。
繼承的本意在于抽象,而非代碼的重用。
-----------------
接口:like a [像](多個接口能被同一個類實作)
接口裡面的方法都是抽象方法。
接口裡面的常量都是靜态不可被改動的。
接口僅僅能實作不能被new。
接口能多實作。
(攻克了java的單實作的問題)
接口能繼承接口。并且接口能夠【多繼承】。
接口的出現是為了定義額外的功能。
接口回調:
1 在Fragment類 中定義一個Test接口。
2 在Fragment類 中定義一個接口對象常量。
3 在Fragment類 中定義一個方法。為接口的引用指派,參數是實作類的子類。
4 在MainActivity類 中實作Test接口。重寫接口裡面的方法。在方法裡面寫上自己的邏輯。
5 在TestCallBack類 中new Fragment這個對象。
調用執行個體化接口的那個方法。參數是new MainActivity();(假設執行null,就傳this吧)
-----------------
3 多态:
父類或接口的引用指向子類的執行個體對象。
優點:提高了代碼的拓展性。
壞處:不能使用子類的特有内容。
假設想使用子類的特有功能,就得向下轉型。
instanceof:向下轉型的keyword,僅僅能用于引用類型的推斷。
多态-成員變量:編譯執行都看左邊。
多态-成員函數:編譯看左邊,執行看右邊。
-----------------------------------------------
多線程:
程序:正在運作的任務程式。
線程:程式運作的程式。
自己定義線程執行的任務都執行在run方法中。
當調用。start()方法後,線程内部。會自己主動運作run() 方法;
有2種方式建立線程。
1 實作Runnable接口。(這個比較好可以起拓展用的)
2 繼承 Thread 類。
(這個比較寫死)
同步鎖:
僅僅要保證鎖是同一個鎖就不會出現線程安全的問題。
JDK 1.5 之後。Lock替代了同步,Condition替代了Object中的螢幕方法。
private final Lock lock=new ReentrantLock();//建立鎖對象
private Condition xiaofei=lock.newCondition();//子鎖1
private Condition shencan=lock.newCondition();//子鎖2
lock.lock();//加鎖
xiaofei.await(); //等待
shencan.signal(); //喚醒
lock.unlock();//解鎖
----------------------------------------------
eclipse 模闆
方法中去掉無用的凝視 java->code style ->code templates
自己定義快捷鍵 java->Editor-> Templates
StringBuffer(線程安全,在多線程的時候使用) StringBuilder(線程不安全,沒有線程的時候。開發中建議使用這個)
字元串比較。實作 Comparable 接口,調用 Comparto()方法,會依照字典大小排序。他的傳回值是0或1。
基本資料類型,字元串轉為對象 Character
toLowerCase(char ch);【指定字元串:變小寫】
toUpperCase(cher ch);【指定字元串:變大寫】
------------
toBinatyString 二進制
toHexString 十六進制
toOctalString 八進制
==================================================集合 記住 Collection 下的集合都能被疊代 Iterator
集合長度可變。數組長度不可變。
集合能夠存儲多種類型對象,數組僅僅能存儲單一類型的對象。
Iterator是Collection全部子集合共性抽取的疊代接口;
Collection[接口] (集合都有:增,删。改,查。的方法)
List: 連結清單結構:能夠模仿堆棧。
注意問題:在疊代集合的時候,/*假設須要對集合進行并發操作,會出現并發改動異常*/,我們得把Iterator 換為ListIterator。
他的功能比 Iterator很多其它。(詳情檢視api)
非線程安全:
ArrayList 查詢快。增删慢。
LinkedList 增删快。查詢慢。 【能夠用來模仿堆棧 addLast(),removeFlast()】
/*線程安全*/。在多線程的時候使用:
Vector 底層是數組結構。他疊代的時候能夠用枚舉接口, Enumeration 來疊代。由于枚舉在的時候還沒有集合架構。
Set: 集合結構:能夠用來去重。
HashSet 無序的。
存儲時速度巨快,由于底層是依據雜湊演算法來實作的。
可是不關心順序,而且唯一。
須要查詢hashCode() 和equers()
自己定義對象(往哈希表中存儲資料的時候)要重寫 equals(),HashCode() 方法。
才幹做比較。
自己定義對象(假設想讓對象具備比較大小的功能,依照自然順序排序,必需要實作 Comparable接口 )
eg:/*牛逼的equers()方法
public boolean equers(Object obj){
if(this==obj){//比較位址
return true;
}
if(!(obj instanceof Student)){
throws new ClassCastException("類型不比對,無法比較");
Student stu=(Student) obj;
return this.name.equals(stu.name) && this.age==stu.age;
}
*/
TreeSet:
排序方式1:
使用元素的自然順序進行排序。他保證資料的唯一性,是在自己定義對象中實作 Comparable接口 重寫compareTo()看傳回值是否為0,為0就是反複的元素。
排序方式2:
定義一個比較器,讓對象一初始化就具備比較功能。實作 Comparator 接口。
重寫 compare()方法,相等傳回0;
假設須要先依照字典排序又要依照長度排序,那麼就得在compare()裡面繼續調用 compareTo() 方法了。
實作原理是二叉樹比較法。就像二分查找法一樣。
person p=(person)o;
int temp =this.age-p.age;
return temp==0?this.name.compareTo(p.name):temp;
LinkedHashSet:
有序且去反複的清單:
範型:
上邊界: ?
extends person (傳遞進來的參數僅僅能為 person的本身或者子類型)
下邊界: person super ? ()
泛型類:
省去了以前的強轉和類型轉換異常的麻煩。(将泛型定義在類上。使用者僅僅須要在使用這個類的時候傳入泛型就能夠了)
詳細什麼類型由使用者确定。
eg: public Util<T>{ //使用方僅僅須要 這樣使用 Util<Person> u=new Util<Person>
private T t;// u.setT(new Person());
public void setT(T t){// u.getT();
this.t=t;
}
public T getT(){
return t;
}
泛型方法:在不确定方法的參數的時候,須要什麼類型自己傳遞 (基本資料類型。或者對象類型,都能夠)
eg: public <W> void show(W w){
System.out.println("w:"+w);
泛型接口:也是傳入的參數不确定的時候使用的。
eg:public interfrace inner<V>{
public abstract void show(V v);
class innerImpl<C> implements inner<C>{
public void show(C c){
System.out.println("c:"+c);
main(String[] args){
new innerImpl<Integer>().show(new Integer(3));
new innerImpl<String>().show(new String("ok"));
fore() 循環。不操作角标,能操作數組和 Connection集合;
Map(Key,Value):
key不能反複;
取值有2種方式:
1 map.keySet 得到全部key的集合
2 map.entrySet 得到全部key和value的集合 (entry 實體對象)
1.0 Hashtable 線程安全,key value不同意為空(和Vector一個時代的)
1.2 HashMap 線程不安全,key value同意為空【假設是自己定義對象,在疊代的時候要去除反複的key,能夠參閱 250行牛逼的equers()方法】
TreeMap 底層是二叉樹實作的,假設想讓自己定義對象也具有比較性,必須實作 Comparable接口,查詢 compareTo();
LinkedHashMap 有序結構的連結清單集合(内部模拟了堆棧的實作)
//Properties 他也是鍵值對的屬性集。重要的是他能持久化這個集合,用于IO流讀取。他的父類是HashTable
專門操作集合的工具類:
Collections eg:詳情檢視api; 工具類中有,synchronizedCollection(),List,Map能夠将非同步的集合轉為同步的集合。
Arrays eg:詳情檢視api; asList(int[] i)數組轉集合。
可是有些方法是不能用的。
由于集合是固定的。不能做增删操作。
toArray()集合轉數組。
定義類型必須一緻。
可變參數: ... 能夠替代非常多個數的數組,前提是必須放在參數清單的最後面。
其它api:
System: 有一個非常有意思的api。 System.getProperties()他能傳回這個整個環境和工具的資訊的集合。
還能夠通過集合裡面特定的key值,能夠在不同平台下都能使用的特殊功能符号。
Runtime:這是一個底層由單例模式完畢的執行時類。 通過Runtime.getRuntime()能夠得到他的對象。詳情檢視 api
eg:啟動qq Runtime.getRuntime().extc("qq.exe");{這裡面,寫的的是Dos指令}
Math: abs()絕對值 , ceil 天花闆 floor地闆 round四舍五入 Max最大 Min最小 pow幂運算,... 正旋餘弦 很多其它檢視api
IO流:用來處理裝置間的傳輸資料。分輸出流和輸入流。
{僅僅要對象一建立就有檔案。
假設已經存在會被覆寫}
使用完之後一定要記得關閉流對象。并且得放在finally中,并且這個流對象還得做非空推斷,防止對象沒有建立成功,報null異常。
因為作業系統不同。有的時候\r\n 不好使,是以我們使用 System.getProperty("line.separator");
位元組流:
InputStream OutputStream: (看頂層,用底層)
FileInputStream
FileOutputStream
位元組流能夠直接将内容寫到目的地,不須要暫時存儲就能操作檔案,比字元流少了走緩沖區這一步。
他是直接操作位元組的。
裝飾模式:
BufferedInputStream 對已有的對象提供了額外的功能,還不用對源對象進行改動,避免了繼承的臃腫。
BufferedOutputStream
轉換流:(事實上我想說:他也是代理模式麼?)
InputStreamReader(new InputStream()):位元組轉字元,将記憶體看不懂的位元組轉為能夠看懂的文字。
OutputStreamWriter(new OutputStream()):字元轉位元組。将看的懂的文字轉為記憶體為看不懂的位元組。
字元流:(位元組流+編碼表)
Reader Writer:
FileWriter FileReader
檔案操作流。
對檔案進行續寫 new FileWriter("demo.txt",true);
在記憶體中定義高效的緩沖區:(一般擷取記憶體中的速度遠比直接擷取目的地的資料快高效)
BufferedReader(new FileReader()); BufferedWriter(new FileWriter());
[事實上BufferedReader 這樣的方式是典型的裝飾模式的應用:對已有的對象提供了額外的功能,還不用對源對象進行改動,避免是繼承的臃腫]
BufferedReader(new FileReader());
LineNumberReader(new FileReader());
IO流4步曲
1 明白源和目的 I O
2 是否純文字 FileReader
3 明白裝置
4 是否須要高效 BufferReader
轉行流:
InputStreamReader(),指定編碼表 InputStreamReader(is,"UTF-8");
OutputStreamWriter(),指定編碼表 OutputStreamWriter(os,"UTF-8");
File 類:
File.separator 名稱分隔符,在不論什麼環境下都能使用。linux和windows下都能識别。他會自己主動轉換
File.getTotalSpace() 總大小
File.getFreeSpace() 剩餘空間
File.deleteOnExit();退出系統的時候會自己主動删除檔案(是以在我們建立檔案之後能夠立刻寫這句話)
File.isFile() 是否為檔案
File.isDirectory() 是否為目錄
file.list(new filter());檔案過濾器
file.listFilse(new filter());目錄過濾器
SequenceInputStream 合并流:
public static void main(String[] args) throws IOException {
将多個流進行邏輯串聯(進行合并,變成一個流,操作起來非常友善,由于多個源變成了一個源)
FileInputStream fis1 = new FileInputStream("tempfile\\seq_1.txt");
FileInputStream fis2 = new FileInputStream("tempfile\\seq_2.txt");
FileInputStream fis3 = new FileInputStream("tempfile\\seq_3.txt");
ArrayList<FileInputStream> v = new ArrayList<FileInputStream>();
v.add(fis1);
v.add(fis2);
v.add(fis3);
Enumeration<FileInputStream> en = Collections.enumeration(v);
SequenceInputStream sis = new SequenceInputStream(en);
//建立目的。
FileOutputStream fos = new FileOutputStream("tempfile\\seq_4.txt");
byte[] buf = new byte[1024];
int len = 0;
while((len=sis.read(buf))!=-1){
fos.write(buf,0,len);
}
fos.close();
sis.close();
RandomAccessFile:多線程下載下傳專用流。
seek(8); 能随機操作指針的方法,能夠開啟多個線程同一時候操作這個對象。達到多線程下載下傳。
從看不懂到看得懂解碼,從看的懂到看不懂,編碼。
檔案加密:
public static void main(String[] args) throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("copy4.mp3")); // 建立流對象,并給流對象加上緩沖區
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy5.mp3"));
// byte[] buf=new byte[1024]; 操作位元組的時候,自己定義的緩存數組就不要了,會導緻垃圾産生
int b=0;
while ((b = bis.read(/*buf*/)) != -1) {
bos.write(b ^ 111);//這個11 就是密鑰
bis.close();
bos.close();
網絡程式設計:
UDP:
不須要建立連接配接速度快。資料限制大小在64k之内,無連接配接,不可靠協定。
TCP:
須要建立連接配接。經過3次握手。能夠進行大傳輸資料,是可靠協定,但效率會稍低。
TCP協定,多線程上傳檔案,源代碼
public class UploadPicClient {
public static void main(String[] args) throws UnknownHostException, IOException {
if(args.length!=1){
System.out.println("請指定檔案");
return;
File file = new File(args[0]);
if(!(file.exists() && file.isFile())){
System.out.println("該檔案不存在,或不是正确的檔案,又一次指定");
if(!(file.getName().endsWith(".jpg") || file.getName().endsWith(".gif"))){
System.out.println("檔案擴充名必須是jpg。或者而是 gif。");
if(file.length()>=1024*1024*2){
System.out.println("檔案過大,又一次選擇,");
Socket s = new Socket("192.168.1.100",10006);
FileInputStream fis = new FileInputStream(file);
OutputStream out = s.getOutputStream();
while((len=fis.read(buf))!=-1){
out.write(buf,0,len);
//告訴server端,發送資料完成,發送一個結束标記。
s.shutdownOutput();
InputStream in = s.getInputStream();
byte[] bufIn = new byte[1024];
int lenIn = in.read(bufIn);
String info = new String(bufIn,0,lenIn);
System.out.println(info);
fis.close();
s.close();
public class UploadPicServer {
//服務端,接收client發送過來的圖檔資料。 進行存儲後,回饋一個 上傳成功字樣。 多使用者的并發訪問。
ServerSocket ss = new ServerSocket(10006);
while(true){
Socket s = ss.accept();
new Thread(new UploadThread(s)).start();
// ss.close();
public class UploadThread implements Runnable {
private Socket s;
public UploadThread(Socket s) {
super();
this.s = s;
@Override
public void run() {
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip+"......connected");
try{
//讀取資料。網絡。
File dir = new File("c:\\mypic");
if(!dir.exists())
dir.mkdir();
int count = 1;
File file = new File(dir,ip+".jpg");
while(file.exists()){
file = new File(dir,ip+"("+(count++)+").jpg");
//目的:檔案
FileOutputStream fos = new FileOutputStream(file);
while((len=in.read(buf))!=-1){
out.write("上傳成功".getBytes());
catch(IOException e){