Vous pouvez créer divers modèles de code Java dans Eclipse via
Fenêtre> Préférences> Java> Editeur> Modèles
par exemple
sysout
est étendu à:
System.out.println(${word_selection}${});${cursor}
Vous pouvez activer ceci en tapant sysout
suivi de CTRL+SPACE
Quels modèles de code Java utiles utilisez-vous actuellement?
Inclure le nom et la description de celui-ci et pourquoi c’est génial.
Il y a une prime ouverte à cela pour une utilisation originale / originale d’un modèle plutôt qu’une fonctionnalité existante intégrée.
Les modèles de code suivants créeront tous deux un enregistreur et créeront les importations appropriées, si nécessaire.
SLF4J
${:import(org.slf4j.Logger,org.slf4j.LoggerFactory)} private static final Logger LOG = LoggerFactory.getLogger(${enclosing_type}.class);
Log4J 2
${:import(org.apache.logging.log4j.LogManager,org.apache.logging.log4j.Logger)} private static final Logger LOG = LogManager.getLogger(${enclosing_type}.class);
Log4J
${:import(org.apache.log4j.Logger)} private static final Logger LOG = Logger.getLogger(${enclosing_type}.class);
Source
JUIL
${:import(java.util.logging.Logger)} private static final Logger LOG = Logger.getLogger(${enclosing_type}.class.getName());
Quelques modèles supplémentaires ici: Link I – Link II
J’aime celui la:
readfile
${:import(java.io.BufferedReader, java.io.FileNotFoundException, java.io.FileReader, java.io.IOException)} BufferedReader in = null; try { in = new BufferedReader(new FileReader(${fileName})); Ssortingng line; while ((line = in.readLine()) != null) { ${process} } } catch (FileNotFoundException e) { logger.error(e) ; } catch (IOException e) { logger.error(e) ; } finally { if(in != null) in.close(); } ${cursor}
MISE À JOUR : La version Java 7 de ce modèle est la suivante:
${:import(java.nio.file.Files, java.nio.file.Paths, java.nio.charset.Charset, java.io.IOException, java.io.BufferedReader)} try (BufferedReader in = Files.newBufferedReader(Paths.get(${fileName:var(Ssortingng)}), Charset.forName("UTF-8"))) { Ssortingng line = null; while ((line = in.readLine()) != null) { ${cursor} } } catch (IOException e) { // ${todo}: handle exception }
MessageFormat – entoure la sélection avec un MessageFormat.
${:import(java.text.MessageFormat)} MessageFormat.format(${word_selection}, ${cursor})
Cela me permet de déplacer un curseur sur une chaîne, d’étendre la sélection à la chaîne entière (Maj-Alt-Haut), puis deux fois sur Ctrl-Espace.
lock – entoure les lignes sélectionnées avec un locking final. Supposons la présence d’une variable de locking.
${lock}.acquire(); try { ${line_selection} ${cursor} } finally { ${lock}.release(); }
NB ${line_selection}
modèles ${line_selection}
apparaissent dans le menu Surround With (Alt-Maj-Z).
Je sais que je frappe un poteau mort, mais je voulais partager cela pour mon intérêt:
Une version correcte du modèle de génération de singleton, qui surmonte la conception de locking à double vérification défectueuse (discutée ci-dessus et mentionnée ailleurs où)
Singleton Creation Template: Nommez cette createsingleton
static enum Singleton { INSTANCE; private static final ${enclosing_type} singleton = new ${enclosing_type}(); public ${enclosing_type} getSingleton() { return singleton; } } ${cursor}
Pour accéder aux singletons générés en utilisant ci-dessus:
Singleton reference Template: Nommez ce getsingleton
:
${type} ${newName} = ${type}.Singleton.INSTANCE.getSingleton();
Pour le log
, un petit utilitaire utile à append dans la variable membre.
private static Log log = LogFactory.getLog(${enclosing_type}.class);
Ajoutez l’extrait de code pour effectuer une itération sur Map.entrySet()
:
${:import(java.util.Map.Entry)} for (Entry<${keyType:argType(map, 0)}, ${valueType:argType(map, 1)}> ${entry} : ${map:var(java.util.Map)}.entrySet()) { ${keyType} ${key} = ${entry}.getKey(); ${valueType} ${value} = ${entry}.getValue(); ${cursor} }
for (Entry entry : properties.entrySet()) { Ssortingng key = entry.getKey(); Ssortingng value = entry.getValue(); | }
if( ${word_selection} != null ){ ${cursor} } if( ${word_selection} == null ){ ${cursor} }
Créez une maquette avec Mockito (dans le contexte “Java des déclarations”):
${:importStatic('org.mockito.Mockito.mock')}${Type} ${mockName} = mock(${Type}.class);
Et dans “Membres de type Java”:
${:import(org.mockito.Mock)}@Mock ${Type} ${mockName};
Mock une méthode vide pour lancer une exception:
${:import(org.mockito.invocation.InvocationOnMock,org.mockito.stubbing.Answer)} doThrow(${RuntimeException}.class).when(${mock:localVar}).${mockedMethod}(${args});
Mock une méthode vide pour faire quelque chose:
${:import(org.mockito.invocation.InvocationOnMock,org.mockito.stubbing.Answer)}doAnswer(new Answer
Vérifiez la méthode simulée appelée exactement une fois:
${:importStatic(org.mockito.Mockito.verify,org.mockito.Mockito.times)} verify(${mock:localVar}, times(1)).${mockMethod}(${args});
Vérifier que la méthode simulée n’est jamais appelée:
${:importStatic(org.mockito.Mockito.verify,org.mockito.Mockito.never)}verify(${mock:localVar}, never()).${mockMethod}(${args});
Nouvelle liste liée utilisant Google Guava (et similaire pour hashset et hashmap):
${import:import(java.util.List,com.google.common.collect.Lists)}List<${T}> ${newName} = Lists.newLinkedList();
J’utilise également un énorme modèle qui génère une classe de test. Voici un fragment raccourci que tout le monde devrait personnaliser:
package ${enclosing_package}; import org.junit.*; import static org.junit.Assert.*; import static org.hamcrest.Matchers.*; import static org.mockito.Matchers.*; import static org.mockito.Mockito.*; import org.mockito.Mockito; import org.slf4j.Logger; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import org.junit.runner.RunWith; // TODO autogenerated test stub @RunWith(MockitoJUnitRunner.class) public class ${primary_type_name} { @InjectMocks protected ${testedType} ${testedInstance}; ${cursor} @Mock protected Logger logger; @Before public void setup() throws Exception { } @Test public void shouldXXX() throws Exception { // given // when // TODO autogenerated method stub // then fail("Not implemented."); } } // Here goes mockito+junit cheetsheet
Un de mes bien-aimés est:
for (${iterable_type} ${iterable_element} : ${iterable}) { ${cursor} }
Et traceout , puisque je l’utilise beaucoup pour le suivi:
System.out.println("${enclosing_type}.${enclosing_method}()");
Je viens de penser à un autre et je l’ai trouvé sur Internet un jour, const :
private static final ${type} ${name} = new ${type} ${cursor};
Un petit conseil sur sysout – J’aime le renommer en “sop”. Rien d’autre dans les librairies java ne commence par «sop», vous pouvez donc taper rapidement «sop» et boom, cela s’insère.
Lancez une exception IllegalArgumentException avec une variable dans la scope actuelle (illarg):
throw new IllegalArgumentException(${var});
Meilleur
throw new IllegalArgumentException("Invalid ${var} " + ${var});
Rien de bien pour la production de code – mais très utile pour les revues de code
J’ai mon template coderev low / med / high faire ce qui suit
/** * Code Review: Low Importance * * * TODO: Insert problem with code here * */
Et puis, dans la vue Tâches – me montrera tous les commentaires de révision de code que je veux faire apparaître lors d’une réunion.
Quelques autres modèles ici
Comprend:
${imp:import(org.slf4j.Logger,org.slf4j.LoggerFactory)} private static final Logger LOGGER = LoggerFactory .getLogger(${enclosing_type}.class);
Bean Property
private ${Type} ${property}; public ${Type} get${Property}() { return ${property}; } public void set${Property}(${Type} ${property}) { ${propertyChangeSupport}.firePropertyChange("${property}", this.${property}, this.${property} = ${property}); }
PropertyChangeSupport
private PropertyChangeSupport ${propertyChangeSupport} = new PropertyChangeSupport(this);${:import(java.beans.PropertyChangeSupport,java.beans.PropertyChangeListener)} public void addPropertyChangeListener(PropertyChangeListener listener) { ${propertyChangeSupport}.addPropertyChangeListener(listener); } public void addPropertyChangeListener(Ssortingng propertyName, PropertyChangeListener listener) { ${propertyChangeSupport}.addPropertyChangeListener(propertyName, listener); } public void removePropertyChangeListener(PropertyChangeListener listener) { ${propertyChangeSupport}.removePropertyChangeListener(listener); } public void removePropertyChangeListener(Ssortingng propertyName, PropertyChangeListener listener) { ${propertyChangeSupport}.removePropertyChangeListener(propertyName, listener); }
Après Java 7, un excellent moyen de configurer des enregistreurs nécessitant (ou préférant) des références statiques à la classe englobante consiste à utiliser l’API MethodHandles nouvellement introduite pour obtenir la classe d’exécution dans un contexte statique.
Un exemple d’extrait pour SLF4J est:
private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
En plus d’être un simple extrait de code dans un IDE, il est également moins fragile si vous réorganisez certaines fonctionnalités dans une autre classe, car vous ne porterez pas accidentellement le nom de la classe.
Appeler du code sur le thread d’interface graphique
Je lie le modèle suivant au slater
raccourci pour envoyer rapidement le code sur le thread d’interface graphique.
${:import(javax.swing.SwingUtilities)} SwingUtilities.invokeLater(new Runnable() { @Override public void run() { ${cursor} } });
Lors du test avec du code, j’ai parfois manqué de supprimer certains fichiers . Je me suis donc fait un modèle appelé syt .
System.out.println(${word_selection}${});//${todo}:remove${cursor}
Avant de comstackr, je vérifie toujours mes TODO et n’oublierai jamais de supprimer un System.out.
strf -> Ssortingng.format("msg", args)
assez simple mais permet d’économiser un peu de frappe.
Ssortingng.format("${cursor}",)
Obtenez une couleur SWT de l’affichage actuel:
Display.getCurrent().getSystemColor(SWT.COLOR_${cursor})
Suround avec syncexec
PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable(){ public void run(){ ${line_selection}${cursor} } });
Utilisez le modèle de conception singleton:
/** * The shared instance. */ private static ${enclosing_type} instance = new ${enclosing_type}(); /** * Private constructor. */ private ${enclosing_type}() { super(); } /** * Returns this shared instance. * * @returns The shared instance */ public static ${enclosing_type} getInstance() { return instance; }
Et un equalsbuilder, adaptation hashcodebuilder:
${:import(org.apache.commons.lang.builder.EqualsBuilder,org.apache.commons.lang.builder.HashCodeBuilder)} @Override public boolean equals(Object obj) { return EqualsBuilder.reflectionEquals(this, obj); } @Override public int hashCode() { return HashCodeBuilder.reflectionHashCode(this); }
Le modèle pour la déclaration de l’enregistreur est génial.
Je crée également linfo, ldebug, lwarn, lerror pour les niveaux de journalisation que j’utilise plus souvent.
lerror:
logger.error(${word_selection}${});${cursor}
Comme les événements sont un peu difficiles à créer en Java – toutes ces interfaces, méthodes et autres éléments à écrire pour 1 événement -, j’ai créé un modèle simple pour créer tout ce dont vous avez besoin pour un événement.
${:import(java.util.List, java.util.LinkedList, java.util.EventListener, java.util.EventObject)} private final List<${eventname}Listener> ${eventname}Listeners = new LinkedList<${eventname}Listener>(); public final void add${eventname}Listener(${eventname}Listener listener) { synchronized(${eventname}Listeners) { ${eventname}Listeners.add(listener); } } public final void remove${eventname}Listener(${eventname}Listener listener) { synchronized(${eventname}Listeners) { ${eventname}Listeners.remove(listener); } } private void raise${eventname}Event(${eventname}Args args) { synchronized(${eventname}Listeners) { for(${eventname}Listener listener : ${eventname}Listeners) listener.on${eventname}(args); } } public interface ${eventname}Listener extends EventListener { public void on${eventname}(${eventname}Args args); } public class ${eventname}Args extends EventObject { public ${eventname}Args(Object source${cursor}) { super(source); } }
Si vous avez des événements qui partagent un seul EventObject
, supprimez simplement celui personnalisé inséré par le modèle et modifiez les parties appropriées de raise___()
et on____()
.
J’avais écrit un joli et élégant mécanisme d’événement en utilisant une interface générique et une classe générique, mais cela ne fonctionnerait pas à cause de la manière dont Java gère les génériques. = (
Edit : 1) Je suis tombé sur le problème où les threads ajoutaient / supprimaient des écouteurs pendant un événement. La List
ne peut pas être modifiée en cours d’utilisation, j’ai donc ajouté synchronized
blocs synchronized
où la liste des écouteurs est accessible ou utilisée, verrouillant la liste elle-même.
J’ai récemment vu une version similaire à celle-ci lors du couplage avec un très bon développeur et ami, et je pense que cela pourrait être un ajout intéressant à cette liste.
Ce modèle créera une nouvelle méthode de test sur une classe, en suivant l’ approche Given-When-Then du paradigme BDD sur les commentaires, comme guide pour la structuration du code. Il démarrera le nom de la méthode avec “should” et vous permettra de remplacer le rest du nom de la méthode factice “CheckThisAndThat” par la meilleure description possible de la responsabilité de la méthode de test. Après avoir rempli le nom, TAB vous amènera directement à la // Given section
, afin que vous puissiez commencer à taper vos conditions préalables.
Je l’ai mappé aux trois lettres “tst”, avec la description “Les méthodes de test devraient être données quand-alors”;)
J’espère que vous le trouverez aussi utile que lorsque je l’ai vu:
@Test public void should${CheckThisAndThat}() { Assert.fail("Not yet implemented"); // Given ${cursor} // When // Then }${:import(org.junit.Test, org.junit.Assert)}
Injection de spring
Je sais que c’est un peu tard pour le jeu, mais voici ce que j’utilise pour Spring Injection dans une classe:
${:import(org.springframework.beans.factory.annotation.Autowired)} private ${class_to_inject} ${var_name}; @Autowired public void set${class_to_inject}(${class_to_inject} ${var_name}) { this.${var_name} = ${var_name}; } public ${class_to_inject} get${class_to_inject}() { return this.${var_name}; }
Voici un constructeur pour les classes non instanciables:
// Suppress default constructor for noninstantiability @SuppressWarnings("unused") private ${enclosing_type}() { throw new AssertionError(); }
Celui-ci est pour les exceptions personnalisées:
/** * ${cursor}TODO Auto-generated Exception */ public class ${Name}Exception extends Exception { /** * TODO Auto-generated Default Serial Version UID */ private static final long serialVersionUID = 1L; /** * @see Exception#Exception() */ public ${Name}Exception() { super(); } /** * @see Exception#Exception(Ssortingng) */ public ${Name}Exception(Ssortingng message) { super(message); } /** * @see Exception#Exception(Throwable) */ public ${Name}Exception(Throwable cause) { super(cause); } /** * @see Exception#Exception(Ssortingng, Throwable) */ public ${Name}Exception(Ssortingng message, Throwable cause) { super(message, cause); } }
J’aime un commentaire de classe généré comme ceci:
/** * I... * * $Id$ */
Le “I …” encourage immédiatement le développeur à décrire ce que fait la classe. Je semble améliorer le problème des classes non documentées.
Et bien sûr, $ Id $ est un mot-clé CVS utile.
J’ai beaucoup utilisé ces extraits, à la recherche de valeurs null
et de chaînes vides.
J’utilise les modèles “test d’argument” comme premier code dans mes méthodes pour vérifier les arguments reçus.
testNullArgument
if (${varName} == null) { throw new NullPointerException( "Illegal argument. The argument cannot be null: ${varName}"); }
Vous souhaiterez peut-être modifier le message d’exception en fonction du standard de votre entreprise ou de votre projet. Cependant, je recommande d’avoir un message qui inclut le nom de l’argument incriminé. Sinon, l’appelant de votre méthode devra chercher dans le code pour comprendre ce qui a mal tourné. (Une exception NullPointerException
sans message produit une exception avec le message assez absurde “null”).
testNullOrEmptySsortingngArgument
if (${varName} == null) { throw new NullPointerException( "Illegal argument. The argument cannot be null: ${varName}"); } ${varName} = ${varName}.sortingm(); if (${varName}.isEmpty()) { throw new IllegalArgumentException( "Illegal argument. The argument cannot be an empty ssortingng: ${varName}"); }
Vous pouvez également réutiliser le modèle de vérification de null à partir du haut et implémenter cet extrait pour vérifier uniquement les chaînes vides. Vous utiliseriez alors ces deux modèles pour produire le code ci-dessus.
Le modèle ci-dessus pose toutefois le problème suivant: si l’argument in est final, vous devrez modifier le code produit (le ${varName} = ${varName}.sortingm()
échouera).
Si vous utilisez beaucoup d’arguments finaux et que vous voulez vérifier les chaînes vides mais que vous n’avez pas à les couper dans le cadre de votre code, vous pouvez aller avec ceci:
if (${varName} == null) { throw new NullPointerException( "Illegal argument. The argument cannot be null: ${varName}"); } if (${varName}.sortingm().isEmpty()) { throw new IllegalArgumentException( "Illegal argument. The argument cannot be an empty ssortingng: ${varName}"); }
testNullFieldState
J’ai également créé des extraits pour vérifier les variables qui ne sont pas envoyées sous forme d’arguments (la grande différence est le type d’exception, qui est maintenant une exception IllegalStateException
).
if (${varName} == null) { throw new IllegalStateException( "Illegal state. The variable or class field cannot be null: ${varName}"); }
testNullOrEmptySsortingngFieldState
if (${varName} == null) { throw new IllegalStateException( "Illegal state. The variable or class field cannot be null: ${varName}"); } ${varName} = ${varName}.sortingm(); if (${varName}.isEmpty()) { throw new IllegalStateException( "Illegal state. The variable or class field " + "cannot be an empty ssortingng: ${varName}"); }
TestArgument
Ceci est un modèle général pour tester une variable. Il m’a fallu quelques années pour vraiment apprendre à apprécier celle-ci, maintenant je l’utilise beaucoup (en combinaison avec les modèles ci-dessus bien sûr!)
if (!(${varName} ${testExpression})) { throw new IllegalArgumentException( "Illegal argument. The argument ${varName} (" + ${varName} + ") " + "did not pass the test: ${varName} ${testExpression}"); }
Vous entrez un nom de variable ou une condition qui renvoie une valeur, suivie d’un opérande (“==”, “<", ">” etc) et d’une autre valeur ou variable et si le test échoue, le code résultant lancera une exception IllegalArgumentException.
La raison de la clause if légèrement compliquée, avec toute l’expression entourée par “! ()”, Est de permettre de réutiliser la condition de test dans le message d’exception.
Peut-être cela va-t-il semer la confusion chez un collègue, mais seulement s’il doit examiner le code, ce qu’il n’aura peut-être pas à faire si vous jetez ce genre d’exceptions…
Voici un exemple avec des tableaux:
public void copy(Ssortingng[] from, Ssortingng[] to) { if (!(from.length == to.length)) { throw new IllegalArgumentException( "Illegal argument. The argument from.length (" + from.length + ") " + "did not pass the test: from.length == to.length"); } }
Vous obtenez ce résultat en appelant le modèle, en tapant “from.length” [TAB] “== to.length”.
Le résultat est beaucoup plus amusant qu’une “ArrayIndexOutOfBoundsException” ou similaire et peut en fait donner à vos utilisateurs la possibilité de résoudre le problème.
Prendre plaisir!
Je l’utilise pour MessageFormat (en utilisant Java 1.4). De cette façon, je suis sûr que je n’ai pas de concaténations difficiles à extraire lors de l’internationalisation
i18n
Ssortingng msg = "${message}"; Object[] params = {${params}}; MessageFormat.format(msg, params);
Aussi pour la journalisation:
bûche
if(logger.isDebugEnabled()){ Ssortingng msg = "${message}"; //NLS-1 Object[] params = {${params}}; logger.debug(MessageFormat.format(msg, params)); }
Mes quelques préférés sont …
1: Javadoc, pour insérer une doc concernant la méthode étant une méthode d’injection d’object Spring.
Method to set the
I${enclosing_type}
implementation that this class will use. * * @param ${enclosing_method_arguments}I${enclosing_type}
instance
2: Fenêtre de débogage, pour créer un FileOutputStream et écrire le contenu du tampon dans un fichier. Utilisé lorsque vous souhaitez comparer un tampon avec une exécution passée (en utilisant BeyondCompare), ou si vous ne pouvez pas afficher le contenu d’un tampon (via inspect) parce que c’est trop volumineux …
java.io.FileOutputStream fos = new java.io.FileOutputStream( new java.io.File("c:\\xx")); fos.write(buffer.toSsortingng().getBytes()); fos.flush(); fos.close();