1. 程式人生 > >Java筆記丨23 引用與相等

Java筆記丨23 引用與相等

引用與指標

引用的實質就是指標,但它是受控的、安全的

比如:

    會檢查空指標

    沒有指標運算*(p+5)

    不能訪問沒有引用到的記憶體

    自動回收垃圾

 

C語言指標在Java中的體現

(1)傳地址->物件

引用型別,引用本身就相當於指標。可以修改物件的屬性、呼叫物件的方法

基本型別:沒有對應的

如交換兩個整數

void swap(int x,int y){int t=x;x=y;y=t;}

int a=8,b=9;swap(a.b);

一種變通的辦法,傳出一個有兩個分量x,y的物件

(2)指標運算->陣列

*(p+5)可以用args[5]

(3)函式指標->介面、Lambda表示式

例:求積分,執行緒,回撥函式,事件處理

(4)指向結點的指標->物件的引用

class Node{

    Object data;

    Node next;

}

示例:List.java

import java.io.IOException;



public class List {

       private Node Head = null;

       private Node Tail = null;

       private Node Pointer = null;

       private int Length = 0;



       public void deleteAll() {

              Head = null;

              Tail = null;

              Pointer = null;

              Length = 0;

       }



       public void reset() {

              Pointer = null;

       }



       public boolean isEmpty() {

              return (Length == 0);

       }



       public boolean isEnd() {

              if (Length == 0) throw new java.lang.NullPointerException();

              else if (Length == 1) return true;

              else return (cursor() == Tail);

       }



       public Object nextNode() {

              if (Length == 1) throw new java.util.NoSuchElementException();

              else if (Length == 0) throw new java.lang.NullPointerException();

              else {

                     Node temp = cursor();

                     Pointer = temp;

                     if (temp != Tail) return (temp.next.data);

                     else throw new java.util.NoSuchElementException();

              }

       }



       public Object currentNode() {

              Node temp = cursor();

              return temp.data;

       }



       public void insert(Object d) {

              Node e = new Node(d);

              if (Length == 0) {

                     Tail = e;

                     Head = e;

              } else {

                     Node temp = cursor();

                     e.next = temp;

                     if (Pointer == null) Head = e;

                     else Pointer.next = e;

              }

              Length++;

       }



       public int size() {

              return (Length);

       }



       public Object remove() {

              Object temp;

              if (Length == 0) throw new java.util.NoSuchElementException();

              else if (Length == 1) {

                     temp = Head.data;

                     deleteAll();

              } else {

                     Node cur = cursor();

                     temp = cur.data;

                     if (cur == Head) Head = cur.next;

                     else if (cur == Tail) {

                            Pointer.next = null;

                            Tail = Pointer;

                            reset();

                     } else Pointer.next = cur.next;

                     Length--;

              }

              return temp;

       }



       private Node cursor() {

              if (Head == null) throw new java.lang.NullPointerException();

              else if (Pointer == null) return Head;

              else return Pointer.next;

       }



       public static void main(String[] args) throws IOException{

              List a = new List();

              for (int i = 1; i <= 10; i++) a.insert(new Integer(i));

              System.out.println(a.currentNode());

              while (!a.isEnd()) System.out.println(a.nextNode());

              a.reset();

              while (!a.isEnd()) {

                     a.remove();

              }

              a.remove();

              a.reset();

              if (a.isEmpty()) System.out.println("There  is  no  Node  in  List  n");

              System.out.println("You  can  press  return  to  quitn");

              try {

                     System. in .read();

              } catch(IOException e) {}

             

       }

}



class Node {

       Object data;

       Node next;



       Node(Object d) {

              data = d;

              next = null;

       }

}

(5)使用JNI

Java Native Interface(JNI)

它允許Java程式碼和其他語言寫的程式碼進行互動

 

相等==

簡單地說,基本型別是值相等,引用型別是引用相等

但有不少的具體情況需要具體分析:

基本型別

數值型別:轉換後比較。浮點數最好不要直接用==,因為有誤差。

Double.NAN==Double.NAN結果為false(參見JDK的API文件)

boolean型無法與int比較

 

Integer i=new Integer(10);

Integer j=new Integer(10);

System.out.println(i==j);//false

,因為物件是兩個

 

Integer m=10;

Integer n=10;

System.out.println(m==n);//true,因為物件有快取

Integer p=200;

Integer q=200;

System.out.println(p==q);//false,因為物件是兩個

這是為什麼呢?

 

裝箱物件是否相等

int或者short在-128~127時是有快取的,超過則沒有。

列舉、引用物件是否相等

列舉型別:內部進行了唯一例項化,所有可以直接判斷

引用型別:

直接看兩個引用是否一樣

如果要判斷內容是否一樣,則要重寫equals方法

如果要重寫equals方法,則最好重寫hashCode()方法

 

String物件的特殊性

String物件

判斷相等,一定不要用==,要用equals

但是字串常量(String literal)及字串常量會進行內部化,相同的字串常量是==的

示例:TestStringEquals.java

class TestStringEquals{

       public static void main(String[] args) {

              String hello = "Hello", lo = "lo"; // " = "左邊為引用,右邊為常量

              System.out.println( hello == "Hello");  //true

              System.out.println( Other.hello == hello ); //true(另外一個類中有hello也是相等的。凡是相同的字串常量它都合併指向同一地方)

 

              System.out.println( hello == ("Hel"+"lo") ); //true

              System.out.println( hello == ("Hel"+lo) ); //false(這兩個不能合併成一個常量)

             

              System.out.println( hello == new String("Hello")); //false(new重新建立的一個物件,它和原先的那個常量沒有關係)

              System.out.println( hello == ("Hel"+lo).intern()); //true(求得它內部的字串)

       }

}

class Other { static String hello = "Hello"; }