歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Java學習遇到的問題

Java學習遇到的問題

日期:2017/3/1 9:27:42   编辑:Linux編程

一. Java中泛型如何比較大小,繼承Comparable類,然後實現其唯一的方法compareTo():

1 public class GenericClass<E extends Comparable<E>>{
2 public int com(E e1, E e2){
3 return e1.compareTo(e2);
4 }
5 }

二. Java中參數傳值還是傳引用的問題:

  按值傳遞意味著當將一個參數傳遞給一個函數時,函數接收的是原始值的一個副本。因此,如果函數修改了該參數,僅改變副本,而原始值保持不變。

  按引用傳遞意味著當將一個參數傳遞給一個函數時,函數接收的是原始值的內存地址的一個副本,而不是值的副本。因此,如果函數修改了該參數,調用代碼中的原始值也隨之改變。但是指向原始對象的引用不會改變!

下面從賦值語句和java方法的參數列表兩方面分別敘述:

  賦值語句:

    對象類型的對象賦值時是按引用傳遞的;八大基本類型(int、long、double、float、byte、boolean、char)的對象賦值時是按值傳遞的;

StringBuffer s = new StringBuffer("good");
StringBuffer s2 = s; //按引用傳遞,s和s2指向的是內存中的同一個地址
s2.append(" afternoon!");
System.out.println(s); //good afternoon

int i =5;
int i2 =i; //按值傳遞
i2 = 6;
System.out.println(i); //5

Java方法的參數列表:

參數列表中,對象類型的對象是按引用傳遞的,但無論方法體內進行了何種操作,都不會改變實參對象的引用;

八大基本類型(int、long、double、float、byte、boolean、char)的對象是按值傳遞的;

public class test {
public static void main(String[] args) {
StringBuilder s = new StringBuilder("good"); //good
StringBuilder s2 = new StringBuilder("bad"); //bad
test(s,s2); //按引用副本傳遞,但是不管test()方法的內部對s,s2指向的對象的內容作了什麼樣的修改,s和s2所指向的對象不會改變
               //通俗一點說就是:將s和s2看做指針的話,指針指向的對象的內容不管如何變化,s和s2這個指針絕對不會變
System.out.println(s); //goodhah2 ,此處即為s指向的對象內容從good變為了goodhah2
System.out.println(s2); //bad
}

public static void test(StringBuilder s,StringBuilder s2){
System.out.println(s); //good
System.out.println(s2); //bad
s2=s; //按引用副本傳遞
s = new StringBuilder("new"); //s指向一個新的對象
System.out.println(s); //new
System.out.println(s2); //good
s.append("hah");
s2.append("hah2");
System.out.println(s); //newhah
System.out.println(s2); //goodhah
}
}

【總結】:

  1. 不管Java參數的類型是什麼,一律傳遞參數的副本。如果Java是傳值,那麼傳遞的是值的副本;如果Java是傳引用,那麼傳遞的是引用的副本。

  2. 不管是賦值語句,還是java方法的參數列表,基本數據類型是傳值(副本),對象類型傳引用(副本)。

三. equals()和==的比較

  1. equals方法對於字符串來說是比較內容的,而對於非字符串來說是比較其指向的對象(引用地址)是否相同的。

    == 比較符是比較指向的對象是否相同的,也就是對象在對內存中的的首地址。

  2. equals 方法是 java.lang.Object 類的方法,Object類中的equals方法是用來比較“地址”的,但是String類中重新定義了equals這個方法,而且比較的是值,而不是地址。

  3. 如果是基本類型(byte, short, int, long, float, double, char,boolean)比較,那麼只能用==來比較,不能用equals();

  4. 對於基本類型的包裝類型,比如Boolean、Character、Byte、Shot、Integer、Long、Float、Double等的引用變量,==是比較地址的,而equals是比較內容的。

  5. 注意一個基本的原則:在定義一個類的時候,如果涉及到對象的比較,應該重寫equals()方法。

四. java中的堆、棧、常量池

  棧:存放八大基本類型的數據和對象的引用,但對象本身不存放在棧中,而是存放在堆中

  堆:存放用new產生的數據,由垃圾回收來負責的

     【棧中的變量指向堆內存中的變量,這就是 Java 中指針的思想】

  靜態域:存放在對象中用static定義的靜態成員

  常量池:存放常量。常量池(constant pool)指的是在編譯期被確定,並被保存在已編譯的.class文件中的一些數據。除了包含代碼中所定義的各種基本類型(如int、long等等)和對 象型(如String及數組)的常量值(final)還包含一些以文本形式出現的符號引用,比如: 類和接口的全限定名; 字段的名稱和描述符; 方法和名稱和描述符。 虛擬機必須為每個被裝載的類型維護一個常量池。常量池就是該類型所用到常量的一個有序集和,包括直接常量(string,integer和 floating point常量)和對其他類型,字段和方法的符號引用。對於String常量,它的值是在常量池中的。

【總結】:

  a.棧中用來存放一些原始數據類型的局部變量數據和對象的引用(String,數組.對象等等),但不存放對象內容

  b.堆中存放使用new關鍵字創建的對象.

  c.字符串是一個特殊包裝類,其引用是存放在棧裡的,而對象內容必須根據創建方式不同定(常量池和堆).有的是編譯期就已經創建好,存放在字符串常量池中,而有的是運行時才被創建.使用new關鍵字,存放在堆中。

Copyright © Linux教程網 All Rights Reserved