Sự khác biệt giữa tĩnh và cuối cùng?


174

Tôi luôn luôn nhầm lẫn giữa staticfinalcác từ khóa trong java .

Họ khác nhau như thế nào ?

Câu trả lời:


238

Từ khóa tĩnh có thể được sử dụng trong 4 tình huống

  • biến tĩnh
  • phương pháp tĩnh
  • khối mã tĩnh
  • lớp lồng tĩnh

Trước tiên chúng ta hãy xem các biến tĩnh và các phương thức tĩnh.

Biến tĩnh

  • Nó là một biến thuộc về lớp và không thuộc đối tượng (thể hiện).
  • Các biến tĩnh chỉ được khởi tạo một lần, khi bắt đầu thực hiện. Các biến này sẽ được khởi tạo trước, trước khi khởi tạo bất kỳ biến thể hiện nào.
  • Một bản sao duy nhất được chia sẻ bởi tất cả các phiên bản của lớp.
  • Một biến tĩnh có thể được truy cập trực tiếp bằng tên lớp và không cần bất kỳ đối tượng nào.
  • Cú pháp: Class.variable

Phương pháp tĩnh

  • Nó là một phương thức thuộc về lớp chứ không thuộc về đối tượng (thể hiện).
  • Một phương thức tĩnh chỉ có thể truy cập dữ liệu tĩnh. Nó không thể truy cập dữ liệu không tĩnh (các biến thể hiện) trừ khi nó có / tạo một thể hiện của lớp.
  • Một phương thức tĩnh chỉ có thể gọi các phương thức tĩnh khác và không thể gọi một phương thức không tĩnh từ nó trừ khi nó có / tạo một thể hiện của lớp.
  • Một phương thức tĩnh có thể được truy cập trực tiếp bằng tên lớp và không cần bất kỳ đối tượng nào.
  • Cú pháp: Class.methodName()
  • Một phương thức tĩnh không thể tham chiếu thishoặc supertừ khóa trong anyway.

Lớp tĩnh

Java cũng có "các lớp lồng nhau tĩnh". Một lớp lồng tĩnh chỉ là một lớp không hoàn toàn có một tham chiếu đến một thể hiện của lớp bên ngoài.

Các lớp lồng nhau tĩnh có thể có các phương thức cá thể và phương thức tĩnh.

Không có thứ gọi là lớp tĩnh cấp cao nhất trong Java.

Lưu ý bên:

phương thức chính là staticvì nó phải có thể truy cập được để một ứng dụng chạy trước khi bất kỳ việc khởi tạo nào diễn ra.

final từ khóa được sử dụng trong một số bối cảnh khác nhau để xác định một thực thể mà sau này không thể thay đổi.

  • Một finallớp không thể được phân lớp. Điều này được thực hiện vì lý do bảo mật và hiệu quả. Theo đó, nhiều lớp thư viện tiêu chuẩn Java là final, ví dụ java.lang.Systemjava.lang.String. Tất cả các phương thức trong một finallớp là ngầm final.

  • Một finalphương thức không thể bị ghi đè bởi các lớp con. Điều này được sử dụng để ngăn chặn hành vi không mong muốn từ một lớp con làm thay đổi một phương thức có thể rất quan trọng đối với chức năng hoặc tính nhất quán của lớp.

  • Một finalbiến chỉ có thể được khởi tạo một lần, thông qua bộ khởi tạo hoặc câu lệnh gán. Nó không cần phải được khởi tạo tại điểm khai báo: đây được gọi là một blank finalbiến. Một biến đối tượng trống cuối cùng của một lớp phải được gán chắc chắn ở cuối mỗi hàm tạo của lớp mà nó được khai báo; tương tự, một biến tĩnh cuối cùng trống phải được gán chắc chắn trong một bộ khởi tạo tĩnh của lớp mà nó được khai báo; mặt khác, lỗi thời gian biên dịch xảy ra trong cả hai trường hợp.

Lưu ý: Nếu biến là tham chiếu, điều này có nghĩa là biến không thể bị ràng buộc lại để tham chiếu đối tượng khác. Nhưng đối tượng mà nó tham chiếu vẫn có thể thay đổi, nếu ban đầu nó có thể thay đổi.

Khi một lớp bên trong ẩn danh được định nghĩa trong phần thân của một phương thức, tất cả các biến được khai báo finaltrong phạm vi của phương thức đó có thể truy cập được từ bên trong lớp bên trong. Khi nó đã được gán, giá trị của biến cuối cùng không thể thay đổi.


5
. "Một phương thức tĩnh chỉ có thể gọi các phương thức tĩnh khác và không thể gọi một phương thức không tĩnh từ nó." - UNLESS nó có / tạo một thể hiện của lớp.
xagyg

1
Tôi nghĩ rằng trong phương pháp tĩnh, bạn đã đề cập sai. nó có thể làClass.methodName()
Mdhar9e

chúng ta có thể có lớp tĩnh quá. Hãy sửa trong câu trả lời của bạn. Cảm ơn :)
Madhusudan

Kể từ Java 8, một lớp ẩn danh (và lambda) có thể truy cập các biến cuối cùng một cách hiệu quả và không hạn chế từ khóa cuối cùng.
akhil_mittal

38

static có nghĩa là nó thuộc về lớp không phải là một thể hiện, điều này có nghĩa là chỉ có một bản sao của biến / phương thức đó được chia sẻ giữa tất cả các thể hiện của một Class cụ thể .

public class MyClass {
    public static int myVariable = 0; 
}

//Now in some other code creating two instances of MyClass
//and altering the variable will affect all instances

MyClass instance1 = new MyClass();
MyClass instance2 = new MyClass();

MyClass.myVariable = 5;  //This change is reflected in both instances

cuối cùng là hoàn toàn không liên quan, đó là một cách để xác định một lần khởi tạo duy nhất. Bạn có thể khởi tạo khi xác định biến hoặc trong hàm tạo, không ở đâu khác.

lưu ý Một lưu ý về các phương thức cuối cùng và các lớp cuối cùng, đây là một cách nói rõ rằng phương thức hoặc lớp không thể được ghi đè / mở rộng tương ứng.

Đọc thêm Vì vậy, về chủ đề tĩnh, chúng tôi đã nói về các ứng dụng khác mà nó có thể có, đôi khi nó được sử dụng trong các khối tĩnh. Khi sử dụng các biến tĩnh đôi khi cần phải thiết lập các biến này trước khi sử dụng lớp, nhưng thật không may, bạn không nhận được hàm tạo. Đây là nơi mà từ khóa tĩnh xuất hiện.

public class MyClass {

    public static List<String> cars = new ArrayList<String>();

    static {
        cars.add("Ferrari");
        cars.add("Scoda");
    }

}

public class TestClass {

    public static void main(String args[]) {
        System.out.println(MyClass.cars.get(0));  //This will print Ferrari
    }
}

Bạn không được nhầm lẫn với các khối khởi tạo cá thể được gọi trước hàm tạo trên mỗi cá thể.


Theo dõi đầu vào do bạn cung cấp có thể xóa tất cả sự nhầm lẫn nhờ ...final is entirely unrelated, it is a way of defining a once only initialization. You can either initialize when defining the variable or within the constructor, nowhere else.
prashant thakre

2
Đơn giản và rõ ràng như mọi thứ nên được. Câu trả lời được chấp nhận chỉ là .... dài dòng.

22

Cả hai thực sự không giống nhau. staticcác trường là các trường không thuộc về bất kỳ trường hợp cụ thể nào của một lớp .

class C {
    public static int n = 42;
}

Ở đây, statictrường nkhông được liên kết với bất kỳ trường hợp cụ thể nào Cnhưng với toàn bộ lớp nói chung (đó là lý do tại sao C.ncó thể được sử dụng để truy cập vào nó). Bạn vẫn có thể sử dụng một ví dụ Cđể truy cập n? Có - nhưng nó không được coi là thực hành đặc biệt tốt.

final mặt khác chỉ ra rằng một biến cụ thể không thể thay đổi sau khi nó được khởi tạo.

class C {
    public final int n = 42;
}

Ở đây, nkhông thể được chỉ định lại bởi vì nó là final. Một sự khác biệt khác là bất kỳ biến nào cũng có thể được khai báo final, trong khi không phải mọi biến đều có thể được khai báo tĩnh.

Ngoài ra, các lớp có thể được khai báo finalchỉ ra rằng chúng không thể được mở rộng:

final class C {}

class B extends C {}  // error!

Tương tự, các phương thức có thể được khai báo cuối cùng để chỉ ra rằng chúng không thể bị ghi đè bởi một lớp mở rộng:

class C {
    public final void foo() {}
}

class B extends C {
    public void foo() {}  // error!
}

Cảm ơn các đầu vào. Mã đưa ra lỗi: class C {public static int n = 42; } nó nói rằng trường không thể khai báo tĩnh trong loại không tĩnh. Tại sao tôi không thể khai báo hoặc làm Cn?
TechnoC Corner

@TechnoC Corner chỉ các lớp cấp cao nhất ( publiclớp có khả năng xác định tệp) hoặc staticcác lớp bên trong có thể xác định staticcác biến. Các lớp bên trong khác là các thể hiện của lớp bên ngoài và không thể có các biến tĩnh.
zapl

17

sau cùng -

1) Khi chúng tôi áp dụng từ khóa " cuối cùng " cho một biến , giá trị của biến đó không đổi. (hoặc) Một khi chúng ta khai báo một biếncuối cùng . giá trị của biến đó không thể thay đổi.

2) Nó hữu ích khi giá trị biến không thay đổi trong suốt thời gian tồn tại của chương trình

tĩnh -

1) khi chúng ta áp dụng từ khóa " tĩnh " cho một biến , điều đó có nghĩa là nó thuộc về lớp.
2) Khi chúng tôi áp dụng từ khóa " tĩnh " cho một phương thức , điều đó có nghĩa là phương thức có thể được truy cập mà không cần tạo bất kỳ trường hợp nào của lớp


12

static có nghĩa là chỉ có một bản sao của biến trong bộ nhớ được chia sẻ bởi tất cả các phiên bản của lớp.

Các finaltừ khóa chỉ có nghĩa là giá trị không thể thay đổi. Không có final, bất kỳ đối tượng có thể thay đổi giá trị của biến.


3

Tĩnh và cuối cùng có một số khác biệt lớn:

Các biến hoặc lớp tĩnh sẽ luôn có sẵn từ (khá nhiều) ở bất cứ đâu. Cuối cùng chỉ là một từ khóa có nghĩa là một biến không thể thay đổi. Vì vậy, nếu có:

public class Test{    
   public final int first = 10;
   public static int second = 20;

   public Test(){
     second = second + 1
     first = first + 1;
   }
}

Chương trình sẽ chạy cho đến khi nó cố gắng thay đổi số nguyên "đầu tiên", điều này sẽ gây ra lỗi. Bên ngoài lớp này, bạn sẽ chỉ có quyền truy cập vào biến "đầu tiên" nếu bạn đã khởi tạo lớp. Điều này trái ngược với "thứ hai", luôn có sẵn.


3

Hãy nghĩ về một đối tượng như một cái loa. Nếu Loa là một lớp, Nó sẽ có các biến khác nhau như âm lượng, âm bổng, âm trầm, màu sắc, v.v. Bạn xác định tất cả các trường này trong khi xác định lớp Loa. Ví dụ, bạn đã khai báo trường màu bằng một công cụ sửa đổi tĩnh, điều đó có nghĩa là bạn đang nói với trình biên dịch rằng có chính xác một bản sao của biến này, bất kể lớp đã được khởi tạo bao nhiêu lần.

Tuyên bố

static final String color = "Black"; 

sẽ đảm bảo rằng bất cứ khi nào lớp này được khởi tạo, giá trị của trường màu sẽ là "Đen" trừ khi nó không bị thay đổi.

public class Speaker {

static String color = "Black";

}

public class Sample {

public static void main(String args[]) {
    System.out.println(Speaker.color); //will provide output as "Black"
            Speaker.color = "white";
    System.out.println(Speaker.color);  //will provide output as "White"
}}

Lưu ý: Bây giờ khi bạn thay đổi màu của loa là mã cuối cùng, mã này sẽ không thực thi, vì từ khóa cuối cùng đảm bảo rằng giá trị của trường không bao giờ thay đổi.

public class Speaker {

static final String color = "Black";

}

public class Sample {

public static void main(String args[]) {
    System.out.println(Speaker.color); //should provide output as "Black"
            Speaker.color = "white"; //Error because the value of color is fixed.  
    System.out.println(Speaker.color); //Code won't execute.
}}

Bạn có thể sao chép / dán mã này trực tiếp vào trình giả lập của mình và thử.


2

Sự khác biệt dễ dàng,

Final : có nghĩa là Giá trị của biến là Final và nó sẽ không thay đổi ở bất cứ đâu. Nếu bạn nói rằng cuối cùng x = 5 thì có nghĩa là x không thể thay đổi giá trị của nó là cuối cùng cho mọi người.

Tĩnh: có nghĩa là nó chỉ có một đối tượng. giả sử bạn có x = 5, trong bộ nhớ có x = 5 và nó hiện diện bên trong một lớp. nếu bạn tạo một đối tượng hoặc thể hiện của lớp có nghĩa là có một hộp cụ thể đại diện cho lớp đó và các biến và phương thức của nó. và nếu bạn tạo một đối tượng hoặc thể hiện khác của lớp đó, điều đó có nghĩa là có hai hộp của cùng một lớp có x khác nhau bên trong chúng trong bộ nhớ. và nếu bạn gọi cả hai x ở các vị trí khác nhau và thay đổi giá trị của chúng thì giá trị của chúng sẽ khác nhau. hộp 1 có x có x = 5 và hộp 2 có x = 6. nhưng nếu bạn tạo x tĩnh thì có nghĩa là nó không thể được tạo lại. bạn có thể tạo đối tượng của lớp nhưng đối tượng đó sẽ không có x khác nhau. nếu x là tĩnh thì hộp 1 và hộp 2 cả hai sẽ có cùng x có giá trị là 5. Có, tôi có thể thay đổi giá trị của bất kỳ nơi nào vì nó không phải là cuối cùng. Vì vậy, nếu tôi nói hộp 1 có x và tôi thay đổi giá trị của nó thành x = 5 và sau đó tôi tạo một hộp khác là hộp2 và tôi thay đổi giá trị của hộp2 x thành x = 6. thì vì X là tĩnh nên cả hai hộp đều có cùng x. và cả hai hộp sẽ cho giá trị của hộp là 6 vì hộp2 ghi đè lên giá trị từ 5 đến 6.

Cả cuối cùng và tĩnh là hoàn toàn khác nhau. Chung kết là cuối cùng không thể thay đổi. tĩnh sẽ vẫn là một nhưng có thể thay đổi.

"Đây là một ví dụ. Hãy nhớ biến tĩnh luôn được gọi bằng tên lớp của chúng. Bởi vì chúng chỉ là một cho tất cả các đối tượng của lớp đó. Vì vậy, lớp A có x = 5, tôi có thể gọi và thay đổi nó bằng Ax = 6; "


1

Tĩnh là thứ mà bất kỳ đối tượng nào trong một lớp có thể gọi, vốn dĩ thuộc về một loại đối tượng.

Một biến có thể là cuối cùng cho toàn bộ một lớp và điều đó đơn giản có nghĩa là nó không thể thay đổi được nữa. Nó chỉ có thể được đặt một lần và cố gắng đặt lại sẽ dẫn đến lỗi bị ném. Nó rất hữu ích vì một số lý do, có lẽ bạn muốn khai báo một hằng số, không thể thay đổi.

Một số mã ví dụ:

class someClass
{
   public static int count=0;
   public final String mName;

   someClass(String name)
   {
     mname=name;
     count=count+1;
   }

  public static void main(String args[])
  {
    someClass obj1=new someClass("obj1");
    System.out.println("count="+count+" name="+obj1.mName);
    someClass obj2=new someClass("obj2");
    System.out.println("count="+count+" name="+obj2.mName);
  }
}

Wikipedia chứa danh sách đầy đủ các từ khóa java .


Bạn có ý nghĩa gì đối với một đối tượng cụ thể? Bạn có thể vui lòng minh họa.
TechnoC Corner

0

Tôi sẽ không cố gắng đưa ra một câu trả lời hoàn chỉnh ở đây. Đề nghị của tôi sẽ là tập trung vào việc hiểu từng người trong số họ làm gì và sau đó nên biết rằng tác dụng của chúng là hoàn toàn khác nhau và tại sao đôi khi chúng được sử dụng cùng nhau.

staticdành cho các thành viên của một lớp (thuộc tính và phương thức) và nó phải được hiểu ngược lại với các thành viên thể hiện (không tĩnh). Tôi khuyên bạn nên đọc "Tìm hiểu sơ thẩm và các thành viên nhóm" trong Hướng dẫn Java. Tôi cũng có thể được sử dụng trong staticcác khối nhưng tôi sẽ không lo lắng về việc bắt đầu.

finalcó ý nghĩa khác nhau nếu nó được áp dụng cho các biến, phương thức, lớp hoặc một số trường hợp khác. Ở đây tôi thích giải thích Wikipedia tốt hơn.


-1

Các giá trị biến tĩnh có thể được thay đổi mặc dù một bản sao của biến ngang qua ứng dụng, trong khi các giá trị Biến cuối cùng có thể được khởi tạo một lần và không thể thay đổi trong suốt ứng dụng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.