You are never a loser until you quit trying!

Tham trị (pass-by-value) và tham chiếu (pass-by-reference) trong Java




Chào bạn đến với phanlamcoder.blogspot.com!

Ở bài viết này chúng ta sẽ tìm hiểu về Tham trị (pass-by-value) và tham chiếu (pass-by-reference) trong Java


 pass by value java


Khi thao tác với các hàm trong Java, với những người mới bắt đầu sẽ thường lúng túng với việc truyền tham số vào cho các hàm. Tại sao một số trường hợp khi truyền tham số vào cho hàm xong khi thoát ra khỏi hàm giá trị của tham số lúc thì bị thay đổi theo logic của hàm, lúc thì không thay đổi gì? Vấn đề ở đây chính là sự khác nhau của các loại tham số được truyền vào hàm mà đôi lúc người lập trình không để ý đến. Các loại tham số này được chia làm 2 kiểu là truyền giá trị và truyền tham chiếu.
·         Truyền tham trị là gì? Truyền tham chiếu là gì?
Mình tạm áp dụng một cách nhớ có vẻ hơi thô thiển của mình để tránh nhầm lẫn trong trường hợp này: tham trị là cùng giá trị, tham chiếu là cùng chiếu đến một vùng nhớ.

1.      Truyền tham trị

 là truyền / copy giá trị của một biến (A) vào một biến khác (B) để sử dụng trong phạm vi của một hàm. Ở đây mình nói đến từ copy dùng để nhấn mạnh giá trị được truyền vào là một bản sao và lúc này (A) và (B) hoàn toàn độc lập nhau, việc dùng (B) để xử lý trong hàm hoàn toàn không ảnh hưởng gì đến biến ban đầu (A).

2.     Truyền tham chiếu

 là làm biến (B) thành một alias (bí danh) của (A), lúc này (A) gần như là (B) và (B) gần như là (A) vì cả 2 đều tham chiếu đến cùng một đối tượng, mọi thay đổi trên (B) thực tế cũng là thay đổi trên (A)  (việc tại sao lại nói (A) va (B) lúc này gần như nhau sẽ được giải thích rõ hơn ở phần dưới). Từ đó, sau khi thoát ra khỏi hàm, dữ liệu trên vùng nhớ được (A) tham chiếu tới sẽ bị thay đổi theo các thao tác mà ta đã dùng để thay đổi dữ liệu trên vùng nhớ được (B) tham chiếu tới.
·         Làm sao xác định đâu là tham chiếu, đâu là tham trị trong Java?
Sau một hồi giảng giải dài dòng ở trên, có thể bạn sẽ nói mình khùng khi mình phát biểu tiếp câu này:
Java chỉ truyền tham trị, không truyền tham chiếu.
Thêm một câu khẳng định lại:
Phát biểu trên luôn đúng và không có ngoại lệ!
Mình không khùng đâu, cái này từng là lầm tưởng của mình trong một thời gian dài và lầm tưởng này nó phổ biến đến mức có thể xếp vào hàng những lầm tưởng phổ biến nhất đối với các lập trình viên Java. Lầm tưởng đó thường được phát biểu như sau:Kiểu dữ liệu cơ sở được truyền theo tham trị, kiểu object được truyền theo tham chiếu.
Giải thích tiếp Java chỉ truyền tham trị, vậy nó truyền tham trị như thế nào trong trường hợp với kiểu dữ liệu cơ sở và kiểu object.
1.      Kiểu dữ liệu cơ sở: đối với kiểu dữ liệu cơ sở, Java đơn giản là copy giá trị của biến để gán vào tham số. Và như đã nói ở trên, lúc này biến và tham số sử dụng trong hàm là riêng biệt, khi thoát ra khỏi hàm biến không bị thay đổi giá trị.
2.     Kiểu object: khi truyền một biến có kiểu object vào một hàm thì lúc đó có nghĩa ta đã truyền giá trị của biến đó để sử dụng trong hàm, chứ không phải truyền đối tượng được biến đó tham chiếu tới. Vậy giá trị của một biến kiểu object là gì??? Nói có vẻ hơi lạ nhưng có thể nói giá trị của biến kiểu object là địa chỉ của object mà biến đó tham chiếu đến đến. Cho nên lúc này việc thay đổi giá trị của biến kiểu object này bằng cách gán cho một biến kiểu object khác thì object được tham chiếu đến lúc đầu không bị ảnh hưởng, chỉ khi sử dụng các method của chính các object được tham chiếu này thì dữ liệu của object mới được thay đổi sau khi ra khỏi hàm.
 Chúc các bạn học tốt!
Góp ý tại mục bình luận bên dưới 💓

Phân biệt toán tử == và phương thức equals() trong java

Tôi nghĩ vấn đề này trong Java vẫn còn nhiều bạn chưa phân biệt rõ sự khác nhau giữa toán tử “==” và phương thức equal() trong Java, đặc biệt là khi so sánh chuỗi String trong Java. Hôm nay mình viết bài này để mọi người tham khảo và góp ý.
VD1: Giả sử tôi có đoạn code như sau:
String a = new String(“abc”);
String b = new String(“abc”);
System.out.println(“a==b ? ”+ (a==b));// kết quả: a==b?false
System.out.println(“a.equals(b)?” + a.equals(b));// kết quả e.quals(b)?true
Vậy tại sao kết quả lại khác nhau?
Trong JAVA, có 2 kiểu biến: biến tham trị và tham chiếu.
Biến kiểu tham trị bao gồm các kiểu nguyên thủy của JAVA như: int, long, double…
Biến kiểu tham chiếu bao gồm: String, array, kiểu đối tượng…
Khi sử dụng biến kiểu tham trị, JAVA chỉ cho phép bạn sử dụng toán tử so sánh “==”.
Khi sử dụng biến kiểu tham chiếu, JAVA cho phép sử dụng cả toán tử “==” và equals(). Tuy nhiên, khi sử dụng toán tử “==”, bộ xử lý của JAVA sẽ so sánh xem 2 biến tham chiếu này có trỏ đến cùng một đối tượng hay không, còn nếu bạn sử dụng phương thức equals(), bộ xử lý JAVA sẽ so sánh giá trị của 2 biến tham chiếu đó. Điều này lý giải tại sao ở ví dụ trên, khi sử dụng phép toán: a.equals(b) => kết quả trả về bằng true, trong khi a==b => kết quả trả về lại bằng false.
Để hiểu hơn, tôi xét thêm một ví dụ nữa:
String a = new String(“abc”);
String b = a;
System.out.println(“a==b ? ”+ (a==b));// kết quả: a==b?true
System.out.println(“a.equals(b)?” + a.equals(b));// kết quả e.quals(b)?true


Chúc các bạn học tốt!
Góp ý tại mục bình luận bên dưới 💓

Bài tập string trong java



Chào bạn đến với phanlamcoder.blogspot.com!

Ở bài viết này chúng ta sẽ cùng test lại những câu lệnh cơ bản nhé!
Ôn tập lại kiến thức về String trong JAVA!

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package stringjava;

import java.util.Locale;

/**
 *
 * @author Nhu Y
 */
public class StringJava {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        String s1 = "Toi dep trai nhat, toi biet toi dep trai";

        //VI TRI XUAT HIEN CUOI CUNG TRONG CHUOI

        System.out.println(s1.lastIndexOf("toi"));
        

        //XOA MOT KY TU

        System.out.print(removeCharAt(s1, 2));
        

        //THAY THE CHUOI CON TRONG CHUOI CHA

        System.out.print(s1.replaceFirst("dep trai", "thong minh"));
        

        //HAI CACH DAO CHUOI

            //cach 1
        s1 = new StringBuffer(s1).reverse().toString();
            //cach 2
        String temp = "";
        for(int i = s1.length()-1;i>-1;i--)
        {
            temp += s1.substring(i);
            s1 = s1.substring(0,i);
        }
        s1 = temp;
        System.out.print(s1);
        

        //TIM MOT TU TRONG CHUOI

        s1 = "hoc-lap-trinh-java";
        
        System.out.print(s1.indexOf("java"));

        //CHIA NHO CHUOI, VONG LAP FOREACH

        
        String[] arrStr = s1.split("-");
        for(String s : arrStr)
        {
            System.out.print(s+" ");
        }

        //SO SANH HAI VUNG CUA CHUOI

        //str1[14-17] == str2[3,6] ???
        String str1 = "Welcome to my blog";
        String str2 = "My blog is lovely";
        //str1[14-17] = "blog"
        //Vung cua chuoi str1: tu vi tri 14
        //Vung cua chuoi str2: tu vi tri 3, co 4 ki tu ("blog")
        //tra ve true or false
        System.out.print(str1.regionMatches(14, str2, 3, 4));

        //SO SANH THOI GIAN THUC THI CAU LENH

        long startTime = System.currentTimeMillis();
      for(int i=0;i<50000;i++){
         String strF = "hello";
         String strL = "hello"; 
      }
      long endTime = System.currentTimeMillis();
      System.out.println("Time taken for creation" 
      + " of String literals : "+ (endTime - startTime) 
      + " milli seconds" );       
      long startTime1 = System.currentTimeMillis();
      for(int i=0;i<50000;i++){
         String strF1 = new String("hello");
         String strL1 = new String("hello");
      }
      long endTime1 = System.currentTimeMillis();
      System.out.println("Time taken for creation" 
      + " of String objects : " + (endTime1 - startTime1)
      + " milli seconds");
        

    //FORMAT()

    double e = 2.25874;
    System.out.format(Locale.GERMANY,"%1.4f%n%n", e);
    

        //LAY KI TU UNICODE

    System.out.print(s1.codePointAt(2));

    }
   
    
    public static String removeCharAt(String s, int i)
    {
        return s = s.substring(0,i) + s.substring(i+1);
    }
    
}






Chúc các bạn học tốt!
Góp ý tại mục bình luận bên dưới 💓