Czy w Javie istnieje automatyczne wnioskowanie typu?

113

Czy autow Javie istnieje typ zmiennej, taki jak w C ++?

Przykład:

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();

Wiem, że w Javie istnieje ulepszona pętla for, ale czy istnieje opcja auto? Jeśli nie, czy można to zrobić? Mam na myśli nową funkcję w C ++ 11

Gry Brainiac
źródło
1
Wszystko poza typami podstawowymi może być przypisane do zmiennej typu Object, więc w przypadku niektórych operacji możesz użyć, Objectgdzie chcesz auto.
Zyx 2000,
1
żadna java nie ma takiej zmiennej
Aleksei Bulgak
@ Zyx2000: Wtedy użyje to_stringfunkcji obiektu , a nie rzeczywistego obiektu, czyż nie?
Games Brainiac
2
@GamesBrainiac: Nie, użyje wersji zastąpionej, jeśli taka istnieje.
Keppil
2
Termin, którego szukasz, nie jest „auto”, jest to „wnioskowanie o typie”. Istnieje sporo pytań o rodzaj wnioskowania w Javie, chociaż w większości odnoszą się do leków generycznych, więc nie jestem pewien, jak znaleźć duplikat ...

Odpowiedzi:

49

Odpowiedział przed pytaniem było EDYCJI :

Nie, autow Javie nie ma typu zmiennej. Tę samą pętlę można osiągnąć jako:

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

Java ma zmienne lokalne, których zakres mieści się w bloku, w którym zostały zdefiniowane. Podobny do C i C ++, ale nie ma słowa kluczowego auto ani register. Jednak kompilator Java nie pozwoli na użycie zmiennej lokalnej, która nie została zainicjowana jawnie i spowoduje błąd kompilacji (w przeciwieństwie do C i C ++, gdzie kompilator zwykle wyświetla tylko ostrzeżenie). Dzięki uprzejmości: Wikipedia .

Nie, w Javie nie ma żadnego głównego nurtu wnioskowania o typie, takiego jak C ++. Wystąpił błąd RFE, ale został on zamknięty z powodu „Nie zostanie naprawiony”. Podano powód:

Ludzie korzystają z nadmiarowości deklaracji typu na dwa sposoby. Po pierwsze, redundantny typ służy jako cenna dokumentacja - czytelnicy nie muszą szukać deklaracji getMap (), aby dowiedzieć się, jaki typ zwraca. Po drugie, nadmiarowość pozwala programiście zadeklarować zamierzony typ, a tym samym skorzystać z kontroli krzyżowej przeprowadzanej przez kompilator.

GŁUPEK
źródło
10
@GamesBrainiac Nie, wywołania metod są zawsze polimorficzne w Javie. Jednak wielu innych rzeczy (np. Rozwiązanie problemu z przeciążeniem lub dowolna operacja nie zdefiniowana Object) nie może być zrobionych w ten sposób. To naprawdę nie jest dobra odpowiedź, zdarza się, że działa tylko dlatego, że przykład w pytaniu jest słaby.
10
To pytanie dotyczy wnioskowania o typie w C ++ 11, a nie starego użycia autow C i przed C ++ 11. Twoja zmiana jest poza tematem.
4
„Nie o to mi chodziło, kiedy wpiszesz, rzuć to na obiekt, da ci to Object's to_string” Fałsz. Absolutnie w 100% fałszywe.
Louis Wasserman,
140
„Ludzie korzystają z nadmiarowości”. To prawda. Każdego ranka budzę się i myślę „jak mogę uczynić mój kod bardziej zbędnym?”. Ze względu na korzyści.
ahoffer
2
Co więcej, ta odpowiedź jest przestarzała, ponieważ varjest zastrzeżonym słowem kluczowym od wersji Java 9.
6infinity8
69

Może Java 10 ma to, czego Ty (i ja) chcesz, poprzez varsłowo kluczowe.

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

Z propozycji ulepszeń JDK 286


Aktualizacja: Tak , ta funkcja trafiła do wydania Java 10!

sorrymissjackson
źródło
6
Tak, to ulepszenie, ale to słowo kluczowe może działać tylko ze zmiennymi lokalnymi. Nie tak potężny jak wnioskowanie o typie automatycznym w C ++
texasbruce
7
Drobny chwytak: varnie jest słowem kluczowym! Z JLS : „var nie jest słowem kluczowym, ale raczej identyfikatorem o specjalnym znaczeniu jako typ lokalnej deklaracji zmiennej”. Dlatego w przeciwieństwie do słów kluczowych nic nie stoi na przeszkodzie, aby wywołać zmienną lub metodę „var”.
Klitos Kyriacou
2
Słuszna uwaga @KlitosKyriacou. Jeśli jednak wyobrażam sobie, że zastąpię słowo kluczowe „identyfikatorem” - lub nawet „identyfikatorem o specjalnym znaczeniu jako typ deklaracji zmiennej lokalnej” - odpowiedź byłaby mniej jasna, jak sądzę. Ale tak, varrzeczywiście nie ma go na liście słów kluczowych.
sorrymissjackson
To nie jest słowo kluczowe wyłącznie dla zgodności z poprzednimi wersjami. Oprócz tego, że możesz mieć identyfikator o tej nazwie, var pełni rolę słowa kluczowego.
facetus
25

Java 7 wprowadza składnię diamentów

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

W porównaniu ze starą wersją java

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

Krytyczny czytelnik zauważy, że ta nowa składnia nie pomaga w pisaniu pętli for w oryginalnym pytaniu. Wydaje się, że jest to poprawne i całkowicie zamierzone. Zobacz inną odpowiedź, która cytuje bazę danych błędów Oracle.

Tarrasch
źródło
4
To prawda, ale on (i ja) szukamy czegoś takiego: auto integerBox = new Box<Integer>();jest to zwykle używane do uzyskania wartości zwracanej z funkcji, które czasami mogą być złożone, jakHashMap<String, LinkedList<Operation, Set<Integer>>>
Roee Gavirel
1
Właśnie tym problemem zająłem się po przykładach kodu. Wniosek był taki, że Java tego nie robi i to celowo.
Tarrasch
18

W Javie 8 można użyć wnioskowania o typie lambda, aby uniknąć deklarowania typu. Analogią do przykładów pytającego byłoby:

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

z których oba można również uprościć za pomocą odniesień do metod:

object_array.forEach(System.out::println); 
object_array.forEach(ObjectType::do_something_that_only_this_particular_obj_can_do);
Ajit George
źródło
8

Krótko mówiąc, nie, nie ma typu automatycznego. Jeśli wszystko, co robisz, to drukowanie wartości, możesz po prostu odnieść się do wartości jako Object.

SimonC
źródło
albo obliczanie hashCodes, albo zbieranie nazw klas, albo ... wpadłeś na pomysł;) Lista jest jednak krótka. Zobacz dokumentację klasy Object (komentarz przeznaczony dla początkujących, jestem pewien, że wiedziałeś o tym SimonC)
Alexander Malakhov
4

To nie jest rozwiązanie w czystej Javie, jednak dodanie biblioteki o nazwie lombok umożliwi poniższej magii kompilację i działanie bardzo podobne do autosłowa kluczowego w C ++

List<String> strList = Arrays.asList("foo", "bar", "baz");
for (val s: strList){
    System.out.println(s.length());
}
samvel1024
źródło