2013-06-05 27 views
5

Tôi muốn hỏi về các lớp học chung. Điều gì sẽ xảy ra khi tôi tạo ra hai cá thể đối tượng từ một lớp chung chung. Họ có chia sẻ tất cả các thành viên tĩnh hay cả hai đều có thành viên tĩnh riêng của mình?Các lớp học chung có chia sẻ thành viên tĩnh không?

Vì vậy, ví dụ:

public A<?>(){ 
    public static Integer member = 0; 
} 

A<Integer> integer = new A<Integer>(); 
A<String> string = new A<String>(); 

Do cả IntegerString có tài liệu tham khảo cùng đằng sau member?

+2

Câu hỏi của bạn hợp lệ, nhưng mã bạn đăng không hợp lệ: Nó không phải là một hàm tạo hợp lệ, cũng không phải là khai báo lớp. Câu trả lời cho câu hỏi của bạn là: Có, họ chia sẻ mọi thành viên tĩnh. Ngoài ra, bạn có thể tự trả lời câu hỏi: 'System.out.println (integer.member == string.member);' Cái nào giống với 'System.out.println (A.member == A.member);' vì là 'tĩnh') – jlordo

+0

Không khó để kiểm tra ... – Dukeling

+0

Điều gì sẽ xảy ra nếu chính thành viên đó là chung? Giống như 'public class MyClass {public static T member; } '?? –

Trả lời

10
public class A<T>{ 
    public static Integer member = 0; 

    public static void main(String[] args) 
    { 
     A<Integer> integer = new A<Integer>(); 
     A<String> string = new A<String>(); 

     integer.member++; 
     System.out.println(string.member); 
    } 
} 

Output

1 

Vì vậy, có hai trường hợp chia sẻ cùng một biến member.

+2

+1 Ví dụ hay cho câu hỏi. Cũng cần lưu ý rằng 'integer.member ++;' là kiểu xấu, và stylecheckers không khuyến khích mã như thế này. Các thành viên 'static' phải luôn được truy cập theo cách tĩnh, tức là:' A.member ++; '. – jlordo

+0

Khi bạn đang nghi ngờ kiểm tra nó! :) +1 – Pragmateek

0

Có, họ sẽ chia sẻ biến. Các quy tắc về biến lớp tĩnh không thay đổi dựa trên việc sử dụng Generics. Một biến lớp tĩnh được chia sẻ bởi tất cả các cá thể.

+1

Điều này không nên được thực hiện cho các cấp. Trong C++ 'A ' và 'A ' sẽ là các lớp khác nhau với các thành viên dữ liệu tĩnh riêng biệt. –

+0

@NicolaMusatti: Đây là câu hỏi trong thẻ 'java' .... – jlordo

+0

Thật vậy. Tuy nhiên, Java Generics được lấy cảm hứng từ các mẫu C++ và tôi nghĩ điều quan trọng là chỉ ra sự khác biệt. –

0

Tất cả đều chia sẻ thuộc tính tĩnh của chúng vì vì thời gian chạy A<Integer>A<String> không phải là các lớp riêng biệt.

0

Bạn chỉ cần nghĩ rằng generics là dành cho mục đích biên dịch. Khi chạy, không có sự khác biệt giữa A<Integer>A<String>: tất cả các trường hợp là A. Vì vậy, các thành viên tĩnh là phổ biến cho bất kỳ trường hợp bạn có thể tạo, mà không có bất kỳ liên quan đến loại bạn đang sử dụng.

3

Câu hỏi hay nhưng anwser là: không có bạn có thể không vì một lý do rất đơn giản: một lần biên soạn không có những điều như một Integer <> hoặc A < String>, chỉ có A vì cho tương thích ngược lý do Java sử dụng generics type-erasure.

Trong các ngôn ngữ khác như C# mọi thứ sẽ hoạt động như bạn mong đợi vì C# được tạo từ khi bắt đầu bằng Generics.

+0

Cảm ơn bạn đã đề cập đến C#. Bản gốc của suy nghĩ của tôi xuất phát từ một ví dụ C#. – Quirin

+0

Tôi đang ở trong tình huống tương tự: khó quay lại 10 năm trước đây khi sử dụng Java nhưng tôi chắc chắn nó sẽ lấp đầy khoảng trống. :) – Pragmateek

2

Không có lớp chữ nào (A<Integer>.class hoặc Class thể hiện) đại diện cho bất kỳ loại tham số nào (như A<Integer>). Sẽ luôn có duy nhất một phiên bản nguyên bản A (ví dụ: A.class) và đó là phiên bản mà tất cả các thành viên tĩnh đều thuộc về.

Đó là lý do tại sao bạn sẽ không làm điều gì đó như A<Integer>.member, nó phải luôn luôn là phiên bản thô A.member (và đó là một (và chỉ) được chia sẻ bởi tất cả các trường hợp).

Bạn có thể đọc bài viết về chủ đề tại đây - Is there one instances of a static field per instantiation of a generic type?.

Các vấn đề liên quan