java tipo - Qual è un buon caso d'uso per l'importazione statica di metodi?




ritorno comandi (13)

Li uso quando potrò. Ho una configurazione IntelliJ per ricordarmi se dimentico. Penso che sia molto più pulito di un nome di pacchetto completo.

Ho appena ricevuto un commento di recensione che la mia importazione statica del metodo non era una buona idea. L'importazione statica era di un metodo di una classe DA, che ha principalmente metodi statici. Così, nel mezzo della logica del business, ho avuto un'attività che apparentemente sembrava appartenere alla classe attuale:

import static some.package.DA.*;
class BusinessObject {
  void someMethod() {
    ....
    save(this);
  }
} 

Il revisore non era entusiasta di aver cambiato il codice e non l'ho fatto, ma sono in qualche modo d'accordo con lui. Una ragione fornita per l'importazione non statica è stata la confusione in cui è stato definito il metodo, non era nella classe corrente e non in nessuna superclasse, quindi anche un po 'di tempo per identificare la sua definizione (il sistema di revisione basato sul web non ha cliccabile link come IDE :-) Non penso che questo sia importante, le importazioni statiche sono ancora piuttosto nuove e presto ci abitueremo a localizzarle.

Ma l'altro motivo, quello su cui sono d'accordo, è che una chiamata di metodo non qualificata sembra appartenere all'oggetto corrente e non dovrebbe saltare contesti. Ma se appartenesse davvero, avrebbe senso estendere quella super classe.

Quindi, quando ha senso adottare metodi di importazione statici? Quando l'hai fatto? Ti è piaciuto / mi piace il modo in cui appaiono le chiamate non qualificate?

EDIT: L'opinione popolare sembra essere quella dei metodi di importazione statica se nessuno li confonderà come metodi della classe corrente. Ad esempio i metodi da java.lang.Math e java.awt.Color. Ma se abs e getAlpha non sono ambigui, non vedo perché readEmployee sia. Come in molte scelte di programmazione, penso che anche questa sia una preferenza personale.

Grazie per la vostra risposta ragazzi, sto chiudendo la domanda.


Lo uso molto per Color.

static import java.awt.Color.*;

È molto improbabile che i colori vengano confusi con qualcos'altro.


Uso 'import static java.lang.Math. *' Durante il trasferimento di codice pesante matematico da C / C ++ a java. I metodi matematici mappano da 1 a 1 e rendono più facile diffondere il codice porticato senza la qualifica del nome della classe.


Sono d'accordo sul fatto che possono essere problematici dal punto di vista della leggibilità e dovrebbero essere usati con parsimonia. Ma quando si utilizza un metodo statico comune possono effettivamente aumentare la leggibilità. Ad esempio, in una classe di test JUnit, metodi come assertEquals sono ovvi da dove provengono. Allo stesso modo per i metodi di java.lang.Math .


Un altro uso ragionevole per le importazioni statiche è con JUnit 4. Nelle versioni precedenti di JUnit sono stati ereditati metodi come assertEquals e fail poiché la classe di test ha esteso junit.framework.TestCase .

// old way
import junit.framework.TestCase;

public class MyTestClass extends TestCase {
    public void myMethodTest() {
        assertEquals("foo", "bar");
    }
}

In JUnit 4, le classi di test non devono più estendere il TestCase e possono invece utilizzare annotazioni. È quindi possibile importare staticamente i metodi di org.junit.Assert da org.junit.Assert :

// new way
import static org.junit.Assert.assertEquals;

public class MyTestClass {
    @Test public void myMethodTest() {
        assertEquals("foo", "bar");
        // instead of
        Assert.assertEquals("foo", "bar");
    }
}

JUnit documents utilizzano in questo modo.


Efficace Java, Second Edition , alla fine dell'articolo 19 si nota che è possibile utilizzare le importazioni statiche se ci si trova pesantemente utilizzando le costanti da una classe di utilità. Penso che questo principio si applicherebbe alle importazioni statiche di costanti e metodi.

import static com.example.UtilityClassWithFrequentlyUsedMethods.myMethod;

public class MyClass {
    public void doSomething() {
        int foo= UtilityClassWithFrequentlyUsedMethods.myMethod();
        // can be written less verbosely as
        int bar = myMethod();
    }
}

Questo ha vantaggi e svantaggi. Rende il codice un po 'più leggibile a scapito della perdita di alcune informazioni immediate su dove è definito il metodo. Tuttavia, un buon IDE ti permetterà di andare alla definizione, quindi questo non è un grosso problema.

Dovresti comunque usarlo con parsimonia, e solo se ti ritrovi a usare cose del file importato molte, molte volte.

Modifica: aggiornato per essere più specifico dei metodi, poiché è a questo che si riferisce questa domanda. Il principio si applica indipendentemente da ciò che viene importato (costanti o metodi).


Parlando dei test unitari: la maggior parte delle persone usa le importazioni statiche per i vari metodi statici forniti dai framework di simulazione, come when() o verify() .

import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

E naturalmente, quando si usa l'unica affermazione che si dovrebbe usare `assertThat (), è utile importare staticamente i necessari hamcrest matcher, come in:

import static org.hamcrest.Matchers.*;

Raccomando l'uso dell'importazione statica quando si usa OpenGL con Java, che è un caso d'uso che rientra nella categoria "uso intensivo di costanti da una classe di utilità"

Considera che

import static android.opengl.GLES20.*;

ti permette di portare il codice C originale e scrivere qualcosa di leggibile come:

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glUniform1i(samplerUniform, 0);
glBindBuffer(GL_ARRAY_BUFFER, vtxBuffer);
glVertexAttribPointer(vtxAttrib, 3, GL_FLOAT, false, 0, 0);

invece di quella comune bruttezza diffusa:

GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture);
GLES20.glUniform1i(samplerUniform, 0);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vtxBuffer);
GLES20.glVertexAttribPointer(vtxAttrib, 3, GLES20.GL_FLOAT, false, 0, 0);

L'importazione statica IMO è piuttosto una bella funzionalità. È assolutamente vero che la forte dipendenza dall'importazione statica rende il codice illeggibile e difficile da capire a quale classe appartiene un metodo o attributo statico. Tuttavia, nella mia esperienza diventa una caratteristica utilizzabile specialmente quando si progettano classi Util che forniscono alcuni metodi e attributi statici. L'ambiguità che sorge ogni volta che si fornisce l'importazione statica può essere elusa stabilendo standard di codice. Nella mia esperienza all'interno di un'azienda questo approccio è accettabile e rende il codice più pulito e facile da capire. Preferibilmente inserisco il carattere _ in metodi statici frontali e attributi statici (in qualche modo adottati da C) . Apparentemente questo approccio viola gli standard di denominazione di Java, ma fornisce chiarezza al codice. Ad esempio, se abbiamo una classe AngleUtils:

public class AngleUtils {

    public static final float _ZERO = 0.0f;
    public static final float _PI   = 3.14f;

    public static float _angleDiff(float angle1, float angle2){

    }

    public static float _addAngle(float target, float dest){

    }
}

In questo caso l'importazione statica fornisce chiarezza e la struttura del codice mi sembra più elegante:

import static AngleUtils.*;

public class TestClass{

    public void testAngles(){

        float initialAngle = _ZERO;
        float angle1, angle2;
        _addAngle(angle1, angle2);
    }
}

Subito qualcuno può dire quale metodo o attributo proviene da un'importazione statica e nasconde le informazioni della classe a cui appartiene. Non suggerisco di utilizzare l'importazione statica per le classi che sono parte integrante di un modulo e di fornire metodi statici e non statici, poiché in questi casi è importante sapere quale classe fornisce determinate funzionalità statiche.


Devi usarli quando:

  • desideri utilizzare un'istruzione switch con valori enum
  • desideri rendere il tuo codice difficile da capire

Sono utili per ridurre la verbosità, in particolare nei casi in cui vengono chiamati molti metodi importati e la distinzione tra metodi locali e importati è chiara.

Un esempio: codice che coinvolge più riferimenti a java.lang.Math

Un altro: una classe di builder XML in cui anteporre il nome di classe a ogni riferimento nascondeva la struttura che si stava costruendo


Penso che le importazioni statiche siano chiare per NLS in stile gettext.

import static mypackage.TranslatorUtil._;

//...
System.out.println(_("Hello world."));

Ciò indica sia la stringa che una stringa che deve essere estratta e fornisce un modo semplice e pulito per sostituire la stringa con la sua traduzione.


I metodi statici sono i metodi in Java che possono essere chiamati senza creare un oggetto di classe. Appartiene alla classe

Usiamo il metodo statico quando non abbiamo bisogno di essere invocati metodo usando l'istanza.





java static-import