2016-07-19 21 views
5

Mam konstruktora, który ma 4 parametry: String, Object, Object, MyEnum.W jaki sposób Intellij wybiera konstruktora po kliknięciu opcji Znajdź użycie?

public MyClass(String name, Object val1, Object val2, MyEnum cat) { 
// find in usage = 202 
    this.name = name; 
    this.val1 = val1; 
    this.val2 = val2; 
    this.cat = cat; 
} 

w 95% przypadków korzystania ostatni parametr null, tak ja Aby utworzyć następną konstruktora która potrzebuje tylko trzech parametrów i określa ostatnią jako zerową.

Kilka pomysłów przyszło mi do głowy, ale w końcu dałem spróbować następujące rozwiązanie:

  1. Zmień ostatni parametr z MyEnum do Integer (błąd kompilacji - nie ma znaczenia): public MyClass(String name, Object val1, Object val2, Integer cat) - Still wykorzystanie 202 find

  2. Dodaj konstruktora z ostatniego parametru typ obiektu: public MyClass(String name, Object val1, Object val2, Object cat) a teraz pierwszy konstruktora (z Integer) ma 196 zwyczaje i drugi 6.

Dokładnie tego chciałem (mam dokładnie 6 inwokacji z niezerowym ostatnim elementem), ale jaka jest przyczyna takiego zachowania? Czy Intellij dokonuje pewnych sprawdzeń i jeśli typem wejściowym jest MyEnum, to nie można go przekazać jako typu Integer, ale wartość null może zostać przekazana obu, więc dlaczego w przypadku pierwszego konstruktora jest 6 mniej wyników?

Gdy zmieniłem z Object na String (teraz mam 2 konstruktorów z String i Integer), oba dają mi 0, gdy biegnę znajduję użycie.

Dziękuję za wyjaśnienie tego zachowania.

+1

Czy pytasz o prawa Java [zasady przeładowywania] (https://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.4.9)? Czy próbujesz opisać w jakiś sposób, że "Znajdź użytki" w IDEA nie pasuje do tego, co faktycznie robi Java? –

+0

Chcę tylko zrozumieć, w jaki sposób IDEA wybiera wyniki Find Usage w scenariuszu, który napisałem. – ruhungry

Odpowiedz

0

To naprawdę nie jest pytanie IntelliJ, ale pytanie łańcuchowe konstruktora java.

Jeśli istnieje duża szansa kot jest zerowy powinien mieć następujące dwa konstruktory:

public MyClass(String name, Object val1, Object val2) { 
    this(name, val1, val2, null) 
} 

public MyClass(String name, Object val1, Object val2, MyEnum cat) { 
    this.name = name; 
    this.val1 = val1; 
    this.val2 = val2; 
    this.cat = cat; 
} 
1

Jeśli masz zarówno myMethod(Integer a) i myMethod(Object a), wywołanie myMethod(null) wezwie wersji Integer, ponieważ jest bardziej szczegółowo. Podobnie, gdybyś miał tylko myMethod(MyEnum a) i myMethod(Object a), wersja MyEnum byłaby wywoływana, gdyby przekazano zerowy argument. (Zobacz this answer o przeciążeniach zerowych, które odnoszą się do section 15.12.2.5 of the Java Language Specification.) Nie ma żadnej różnicy w sposobie działania w zależności od tego, czy jest to Integer, czy MyEnum; oba są bardziej specyficzne niż obiekt, więc wybrano przeciążenie.

Gdy poprosisz IntelliJ IDEA o znalezienie zastosowań metody, używa ona własnego indeksu kodu i wiedzy o tym, w jaki sposób Java radzi sobie z rozwiązywaniem przeciążenia, aby znaleźć wszystkie przypadki, w których ta metoda zostanie wywołana. Chociaż reguły te mogą być nieco skomplikowane (patrząc na wszystkie szczegóły w Specyfikacji Języka Java sprawia, że ​​moje oczy też boli) i jest możliwe, że istnieje przypadek użycia, w którym IDEA będzie źle i zobaczyć coś inaczej niż sposób kompilator Java i w tym przypadku wygląda na to, że robi to dobrze. To poręczny sposób, aby się z nim bawić i zrozumieć i przetestować działanie mechanizmu przeciążania.