#define in Java

Ik begin te programmeren in Java en ik vraag me af of het equivalent van de C++ #definebestaat.

Een snelle zoektocht op Google zegt dat dit niet het geval is, maar kan iemand me vertellen of er iets soortgelijks bestaat?
op Java? Ik probeer mijn code leesbaarder te maken.

In plaats van myArray[0]wil ik bijvoorbeeld myArray[PROTEINS]kunnen schrijven.


Antwoord 1, autoriteit 100%

Nee, want er is geen precompiler. In uw geval zou u echter hetzelfde als volgt kunnen bereiken:

class MyClass
{
    private static final int PROTEINS = 0;
    ...
    MyArray[] foo = new MyArray[PROTEINS];
}

De compiler zal merken dat PROTEINSnooit, maar dan ook nooit kan veranderen en zal het dus inline zetten, wat min of meer is wat je wilt.

Merk op dat de toegangsmodifier op de constante hier onbelangrijk is, dus het kan publicof protectedzijn in plaats van privé, als je dezelfde constante over meerdere lessen.


Antwoord 2, autoriteit 42%

Reactieruimte te klein, dus hier is wat meer informatie voor u over het gebruik van static final. Zoals ik al zei in mijn reactie op de Andrzej’s antwoord, alleen primitief en Stringworden rechtstreeks in de code gecompileerd als letterlijke waarden. Probeer het volgende om dit te demonstreren:

Je kunt dit in actie zien door drie klassen te maken (in aparte bestanden):

public class DisplayValue {
    private String value;
    public DisplayValue(String value) {
        this.value = value;
    }
    public String toString() {
        return value;
    }
}
public class Constants {
    public static final int INT_VALUE = 0;
    public static final DisplayValue VALUE = new DisplayValue("A");
}
public class Test {
    public static void main(String[] args) {
        System.out.println("Int   = " + Constants.INT_VALUE);
        System.out.println("Value = " + Constants.VALUE);
    }
}

Compileer deze en voer Test uit, die wordt afgedrukt:

Int    = 0
Value  = A

Verander nu Constantsom voor elk een andere waarde te hebben en compileer gewoon klasse Constants. Wanneer u Testopnieuw uitvoert (zonder het klassenbestand opnieuw te compileren), drukt het nog steeds de oude waarde af voor INT_VALUEmaar niet voor VALUE. Bijvoorbeeld:

public class Constants {
    public static final int INT_VALUE = 2;
    public static final DisplayValue VALUE = new DisplayValue("X");
}

Voer Test uit zonder Test.javaopnieuw te compileren:

Int    = 0
Value  = X

Houd er rekening mee dat elk ander type dat wordt gebruikt met static finalals referentie wordt bewaard.

Vergelijkbaar met C/C++ #if/#endif, een constante letterlijke of een gedefinieerd door static finalmet primitieven, gebruikt in een normale Java if-voorwaarde en evalueert naar falsezal ervoor zorgen dat de compiler de bytecode voor de instructies in het if-blok verwijdert (ze zullen niet gegenereerd).

private static final boolean DEBUG = false;
if (DEBUG) {
    ...code here...
}

De code bij “…code here…” zou niet in de bytecode worden gecompileerd. Maar als je DEBUGhebt gewijzigd in true, dan zou dat wel zo zijn.


Antwoord 3, autoriteit 6%

static final int PROTEINS = 1
...
myArray[PROTEINS]

Normaal gesproken zou je “constanten” in de klas zelf plaatsen. En houd er rekening mee dat een compiler de verwijzingen ernaar weg mag optimaliseren, dus verander het niet tenzij je alle gebruikende klassen opnieuw compileert.

class Foo {
  public static final int SIZE = 5;
  public static int[] arr = new int[SIZE];
}
class Bar {
  int last = arr[Foo.SIZE - 1]; 
}

Bewerk cyclus… SIZE=4. Compileer ook Baromdat je compiler misschien net “4” heeft geschreven in de laatste compilatiecyclus!


Antwoord 4, autoriteit 4%

Java heeft geen algemene definepreprocessor-richtlijn.

In het geval van constanten is het aan te raden deze te declareren als static final, zoals in

private static final int PROTEINS = 100;

Dergelijke declaraties zouden door de compilers worden inline gezet (als de waarde een constante tijdens het compileren is).

Houd er rekening mee dat openbare statische definitieve constante velden deel uitmaken van de openbare interface en dat hun waarden niet mogen veranderen (aangezien de compiler ze inline maakt). Als u de waarde wijzigt, moet u alle bronnen die naar dat constante veld verwijzen opnieuw compileren.


Antwoord 5, autoriteit 3%

Er is een preprocessor voor Javadie richtlijnen biedt zoals #define, #ifdef, #ifndef en vele anderen, bijvoorbeeld het PostgresJDBC-team gebruikt het om bronnen voor verschillende gevallen te genereren en om geen code te dupliceren.


Antwoord 6

Meest leesbareoplossing maakt gebruik van Statische import. Dan hoeft u nietAnotherClass.constantte gebruiken.

Schrijf een klasse met de constante als public staticveld.

package ConstantPackage;
public class Constant {
    public static int PROTEINS = 1;
}

Gebruik dan gewoon Static Importwaar je de constante nodig hebt.

import static ConstantPackage.Constant.PROTEINS;
public class StaticImportDemo {
    public static void main(String[]args) {
        int[] myArray = new int[5];
        myArray[PROTEINS] = 0;
    }
}

Voor meer informatie over Static Import, zie deze stack-overflow-vraag.


Antwoord 7

Manifold-preprocessorgeïmplementeerd als een javac-compiler-plug-in is exclusief ontworpen voor voorwaardelijke compilatievan Java-broncode. Het gebruikt de bekende C/C++-stijl van richtlijnen: #define, #undef, #if, #elif, #else, #endif, #error. en #waarschuwing.

Het heeft Maven- en Gradle-plug-ins.


Antwoord 8

Het eenvoudigste antwoord is “Geen directe methode om het te verkrijgen omdat er geen pre-compiler is”
Maar je kunt het zelf doen. Gebruik klassen en definieer vervolgens variabelen als definitiefzodat deze gedurende het hele programma als constant kunnen worden aangenomen
Vergeet niet final en variable te gebruiken als openbaar of beschermd, niet privé, anders heb je er geen toegang toe van buiten die klasse


Antwoord 9

Java Primitive Specializations Generatorondersteunt /* with */, /* define */en /* if */ ... /* elif */ ... /* endif */blokken waarmee voer een soort macro-generatie uit in Java-code, vergelijkbaar met java-comment-preprocessor genoemd in dit antwoord.

JPSG heeft Maven- en Gradle-plug-ins.

Other episodes