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


Answers

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 documenti che lo utilizzano in questo modo.

Question

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.




Le importazioni statiche sono l'unica "nuova" caratteristica di Java che non ho mai usato e non intendo mai usare, a causa dei problemi che hai appena menzionato.




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