Java学習ノートの3(値別転送と参照別転送)


メソッド・パラメータを値で渡し、参照で渡します.
[list]
  • 値による伝達:値による伝達とは、方法の内部でパラメータの値を変更することで伝達された外部オブジェクトに影響を及ぼさない、例えば、
  • である.
    
            int i = 1;
            public void increment(int i){
               i++;
               System.out.println(i);   //   2
            }
            System.out.println(i);   //   1
    
  • リファレンス別転送:リファレンス転送と値別転送は逆に、転送された外部オブジェクトに影響します(Cの「&パラメータ」はリファレンス別転送です).
  • [/list]
    Javaでは値によってしか渡されません.オブジェクトのように、オブジェクトの値を変更する人がいるかもしれません.たとえば、次のようにします.
    
           public class Test{
              int i;
              public void increment(Test t){
                  t.i++;
                  System.out.println(i);   //   1
              }
              public static void main(String[] args){
                  Test t = new Test();
                  t.increment(t);
                  System.out.println(t.i); //    1
              }
           }
    

    これは確かにオブジェクトの値を変更しましたが、オブジェクト参照の値を変更していません.それは元のオブジェクトを指しています.オブジェクト参照はオブジェクトではありません.このような誤った認識は主にオブジェクトとオブジェクト参照の違いを理解していません.オブジェクトを風船と理解することができますが、オブジェクト参照は風船の線を引いていると理解することができます.だからこれは値で伝わります.
    1)「別名」の問題:Javaでは値でしか渡されないため、いくつかのハンドル(オブジェクト参照)が同じオブジェクトを指している場合、オブジェクトの値を変更する必要がある場合があり、必要でない場合があります.これにより、別名の問題が発生します.この問題を解決するには、Object.clone()メソッドを使用して、ローカルコピーオブジェクトを作成することです.
    
          public class TestHandIn implements Cloneable {
             private int in;
             public void testreference(TestHandIn testin){
    	   //      ,         
    	    TestHandIn in = (TestHandIn)testin.clone();
    	    in.in++;
    	    System.out.println(in.in);//   1
    	}
             public Object clone(){
    	   Object obj = null;
    	   try {
    		 obj = super.clone();
                } catch (CloneNotSupportedException e) {
    		System.out.println(e.getMessage());
    	   }
    	   return obj;
    	}
             public static void main(String[] args){
                 TestHandIn in = new TestHandIn();
                 in.testreference(in);
    	    System.out.println(in.in); //   0,    
             }
          }
    

    clone()メソッドはObjectでprotectedであり、サブクラスがclone能力を持つにはこのメソッドを上書きしてCloneableインタフェースを実装する必要があります.これは、各クラスがデフォルトでclone能力を持たないようにするためであり、Object.clone()メソッドはクラスがCloneableインタフェースを実装しているかどうかをチェックするので、Cloneableインタフェースを実装する必要があります.
    2)読み取り専用クラスStringおよびその「同志」クラスStringBufferおよびStringBuilder:まず、次のコードを参照してください.
    
             public void passString(String s){
                s = s + "abc";
                System.out.println(s);  //  123abc
             }
             public static void main(String[] args){
                String s = "123";
                passString(s);
                System.out.println(s);   //  123,     
             }
    

    これは参照伝達パラメータによるように見えますが、Stringクラスの役割です.Stringでは各メソッドが新しいオブジェクトを作成して操作しているので、元のオブジェクトは変更されていません.Stringクラスも読み取り専用クラスと呼ばれ、「別名問題」をよく解決していますが、修正が必要なオブジェクトは面倒で効率的な問題があり、「同志」が現れました.クラスStringBufferとStringBuilder、StringBufferはスレッド同期であり、StringBuilderはそうではなく、効率が高い.StringBufferとStringBuilderのappend()メソッドの変更は、頻繁にオブジェクトを作成する必要はなく、効率は「+」よりも高いが、「+」は直感的に見え、実際の状況に応じて選択されます.
    
             String s = "abc";
             s = s + "def" + "f" + "g" + "h";  //   
              StringBuffer sb = new StringBuffer("abc");
             sb.append("def").append("f").append("g").append("h"); //   
    

    Stringで有用な文字セット変換方法:String.getBytes()とnew String(byte[byte]bytes,String charsetName)は、中国語の問題を解決するのに非常に有用な2つの方法、バイトストリームと文字ストリームの変換ブリッジクラスInputStreamReaderとInputStreamWriterであり、下位実装はこの2つの方法を使用する.