Ik begin te programmeren in Java en ik vraag me af of het equivalent van de C++ #define
bestaat.
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 PROTEINS
nooit, 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 public
of protected
zijn 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 String
worden 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 Constants
om voor elk een andere waarde te hebben en compileer gewoon klasse Constants
. Wanneer u Test
opnieuw uitvoert (zonder het klassenbestand opnieuw te compileren), drukt het nog steeds de oude waarde af voor INT_VALUE
maar 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.java
opnieuw te compileren:
Int = 0
Value = X
Houd er rekening mee dat elk ander type dat wordt gebruikt met static final
als referentie wordt bewaard.
Vergelijkbaar met C/C++ #if
/#endif
, een constante letterlijke of een gedefinieerd door static final
met primitieven, gebruikt in een normale Java if
-voorwaarde en evalueert naar false
zal 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 DEBUG
hebt 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 Bar
omdat je compiler misschien net “4” heeft geschreven in de laatste compilatiecyclus!
Antwoord 4, autoriteit 4%
Java heeft geen algemene define
preprocessor-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.constant
te gebruiken.
Schrijf een klasse met de constante als public static
veld.
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.