Có kiểu suy luận tự động trong Java không?


113

autokiểu biến trong Java như bạn có trong C ++ không?

Một ví dụ:

for ( auto var : object_array)
    std::cout << var << std::endl;

for( auto var : object_array)
    var.do_something_that_only_this_particular_obj_can_do();

Tôi biết rằng có vòng lặp for nâng cao trong Java, nhưng có tự động không? Nếu không, có một hack để làm điều này? Tôi đang đề cập đến tính năng mới trong C ++ 11


1
Mọi thứ ngoại trừ các kiểu cơ bản đều có thể được gán cho một biến kiểu Object, vì vậy đối với một số thao tác, bạn có thể sử dụng Objectở nơi bạn muốn auto.
Zyx 2000

1
không có java không có biến như vậy
Aleksei Bulgak

@ Zyx2000: Sau đó, nó sẽ sử dụng to_stringchức năng của đối tượng , chứ không phải đối tượng thực sự được đề cập, phải không?
Trò chơi Brainiac

2
@GamesBrainiac: Không, nó sẽ sử dụng phiên bản bị ghi đè, nếu có.
Keppil

2
Thuật ngữ bạn đang tìm không phải là "tự động", mà là "kiểu suy luận". Có khá một vài câu hỏi về suy luận kiểu trong Java, mặc dù họ chủ yếu tham khảo Generics, vì vậy tôi không chắc chắn làm thế nào để tìm thấy một bản sao ...

Câu trả lời:


49

Đã trả lời trước khi câu hỏi được CHỈNH SỬA :

Không, không có autokiểu biến trong Java. Vòng lặp tương tự có thể đạt được như:

for ( Object var : object_array)
  System.out.println(var);

Java có các biến cục bộ, có phạm vi nằm trong khối mà chúng đã được xác định. Tương tự như C và C ++, nhưng không có từ khóa auto hoặc register. Tuy nhiên, trình biên dịch Java sẽ không cho phép sử dụng biến cục bộ không được khởi tạo rõ ràng và sẽ gây ra lỗi biên dịch (không giống như C và C ++ trong đó trình biên dịch thường chỉ đưa ra cảnh báo). Lịch sự: Wikipedia .

Không, không có bất kỳ kiểu suy luận chính thống nào trong Java như C ++. Có một RFE nhưng điều này đã bị đóng là "Sẽ không khắc phục", lý do được đưa ra là:

Con người được hưởng lợi từ sự dư thừa của khai báo kiểu theo hai cách. Đầu tiên, kiểu thừa đóng vai trò là tài liệu có giá trị - người đọc không cần phải tìm kiếm khai báo getMap () để biết kiểu mà nó trả về. Thứ hai, dự phòng cho phép lập trình viên khai báo kiểu dự định và do đó được hưởng lợi từ việc kiểm tra chéo do trình biên dịch thực hiện.


10
@GamesBrainiac Không, các lệnh gọi phương thức luôn đa hình trong Java. Tuy nhiên, nhiều thứ khác (ví dụ như giải quyết quá tải, hoặc bất kỳ hoạt động nào không được xác định trên Object) không thể được thực hiện như thế này. Đây không hẳn là một câu trả lời hay, nó chỉ xảy ra hiệu quả vì ví dụ trong câu hỏi là yếu.

10
Câu hỏi này là về kiểu suy luận trong C ++ 11, không phải về cách sử dụng cũ autotrong C và trước C ++ 11. Chỉnh sửa của bạn bị lạc đề.

4
"Đó không phải là ý của tôi, một khi bạn nhập truyền nó vào một Đối tượng, nó sẽ cung cấp cho bạn chuỗi to_string của Đối tượng" Sai. Hoàn toàn sai sự thật 100%.
Louis Wasserman

140
"Con người được hưởng lợi từ sự dư thừa." Đúng rồi. Mỗi buổi sáng tôi thức dậy và nghĩ "làm thế nào tôi có thể làm cho mã của tôi trở nên thừa hơn?". Vì những lợi ích.
ahoffer

2
Hơn nữa câu trả lời này đã lỗi thời vì varlà một từ khóa dành riêng cho Java 9.
6infinity8

69

Có thể là Java 10 có những gì bạn (và tôi) muốn, thông qua vartừ khóa.

var list = new ArrayList<String>();  // infers ArrayList<String>
var stream = list.stream();          // infers Stream<String>

Từ các Đề xuất Cải tiến JDK 286


Cập nhật: Yap, tính năng đó đã được đưa vào bản phát hành Java 10!


6
Đây là một cải tiến, nhưng từ khóa đó chỉ có thể hoạt động với các biến cục bộ. Không mạnh bằng suy luận kiểu tự động C ++
texasbruce 27/02

7
Nit-pick nhỏ: varkhông phải là một từ khóa! Từ JLS : "var không phải là một từ khóa, mà là một định danh có ý nghĩa đặc biệt như kiểu khai báo biến cục bộ". Vì vậy, không giống như từ khóa, không có gì ngăn bạn gọi một biến hoặc một phương thức "var".
Klitos Kyriacou 21/1218

2
Điểm tốt @KlitosKyriacou. Tuy nhiên, nếu tôi tưởng tượng thay thế 'từ khóa' bằng 'số nhận dạng' - hoặc thậm chí 'số nhận dạng có ý nghĩa đặc biệt như kiểu khai báo biến cục bộ' - tôi nghĩ câu trả lời sẽ ít rõ ràng hơn. Nhưng vâng, varthực sự không có trong danh sách các từ khóa.
sorrymissjackson

Nó không phải là một từ khóa chỉ để tương thích ngược. Ngoài thực tế là bạn có thể có một định danh với tên này, var còn đóng vai trò của một từ khóa.
facetus

25

Java 7 giới thiệu cú pháp kim cương

Box<Integer> integerBox = new Box<>(); // Java 7

So với java cũ

Box<Integer> integerBox = new Box<Integer>(); // Before Java 7

Người đọc quan trọng sẽ nhận thấy rằng cú pháp mới này không giúp ích gì cho việc viết các vòng lặp for trong câu hỏi ban đầu. Điều đó có vẻ đúng và hoàn toàn có chủ đích. Xem câu trả lời khác trích dẫn cơ sở dữ liệu lỗi của Oracle.


4
Đúng vậy, nhưng những gì anh ta (và tôi) đang tìm kiếm một cái gì đó như: auto integerBox = new Box<Integer>();, điều này thường được sử dụng để nhận được một giá trị trả về từ một chức năng mà đôi khi có thể được tạo phức nhưHashMap<String, LinkedList<Operation, Set<Integer>>>
Roee Gavirel

1
Mối quan tâm đó là chính xác những gì tôi đã giải quyết sau khi mã mẫu. Kết luận là Java không làm điều đó, và đó là mục đích.
Tarrasch

18

Trong Java 8, bạn có thể sử dụng kiểu suy luận lambda để tránh khai báo kiểu. Tương tự với các ví dụ của người hỏi sẽ là:

object_array.forEach(var -> System.out.println(var)); 
object_array.forEach(var -> var.do_something_that_only_this_particular_obj_can_do());

cả hai đều có thể được đơn giản hóa bằng cách sử dụng tham chiếu phương thức:

object_array.forEach(System.out::println); 
object_array.forEach(ObjectType::do_something_that_only_this_particular_obj_can_do);

8

Tóm lại, không, không có loại tự động. Nếu tất cả những gì bạn đang làm là in giá trị, bạn chỉ có thể tham chiếu đến giá trị dưới dạng một Object.


hoặc tính toán hashCode, hoặc thu thập tên lớp, hoặc ... bạn có ý tưởng;) Tuy nhiên, danh sách này ngắn. Xem tài liệu lớp Object (comment dành cho người mới bắt đầu, tôi chắc chắn rằng bạn biết điều đó SimonC)
Alexander Malakhov

4

Nó không phải là một giải pháp Java thuần túy, tuy nhiên việc thêm một thư viện có tên là lombok sẽ cho phép điều kỳ diệu bên dưới để biên dịch và hoạt động rất giống với autotừ khóa trong C ++

List<String> strList = Arrays.asList("foo", "bar", "baz");
for (val s: strList){
    System.out.println(s.length());
}
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.