【问题标题】:Seeking useful Eclipse Java code templates [closed]寻找有用的 Eclipse Java 代码模板 [关闭]
【发布时间】:2010-11-04 22:59:44
【问题描述】:

您可以通过

在 Eclipse 中创建各种 Java 代码模板

窗口 > 首选项 > Java > 编辑器 > 模板

例如

sysout 扩展为:

System.out.println(${word_selection}${});${cursor}

您可以通过输入 sysout 后跟 CTRL+SPACE 来激活此功能

您目前使用哪些有用的 Java 代码模板?包括它的名称和描述,以及它为什么很棒。

我正在寻找模板的原始/新颖用途,而不是内置的现有功能。

  • 创建 Log4J 记录器
  • 从显示中获取 swt 颜色
  • Syncexec - Eclipse 框架
  • 单例模式/枚举单例生成
  • 读取文件
  • 常量
  • 追踪
  • 格式化字符串
  • 评论代码审查
  • 字符串格式
  • 最后尝试锁定
  • 消息格式 i18n 和日志
  • 平等建设者
  • 哈希码生成器
  • Spring 对象注入
  • 创建文件输出流

【问题讨论】:

  • 是否有任何从 Enum 生成 switch 语句的所有可能情况?我知道你可以用 CTRL+1 做到这一点,但我宁愿使用 cmd 完成。
  • 你能解释一下System.out.println(${word_selection}${});${cursor}是什么意思吗?听起来有一种方法可以选择一个单词并自动将其包含在 sysout 调用中,对吗?怎么样?
  • 您突出显示您想要被 sysout 调用包围的单词,然后按 Ctrl-Space(如果您有很多突出显示模板,则输入模板的名称)
  • @JReader ${} 做什么?

标签: java eclipse templates ide code-generation


【解决方案1】:

如果需要,以下代码模板将创建记录器并创建正确的导入。

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.

七月

${:import(java.util.logging.Logger)}
private static final Logger LOG = Logger.getLogger(${enclosing_type}.class.getName());

【讨论】:

  • 我认为 ${:import ...} 仅适用于较新版本的 Eclipse。我坚持使用 3.2,它对我不起作用。
  • 我的版本 (3.5) 中也没有。有谁知道它是在哪个版本中引入的?
  • 在 3.5 中对我来说效果很好。
  • 我喜欢它!但我将 ${import ...} 放在 Logger 声明下方,这样它就不会添加新行。
  • 对于 log4j2,我必须将模板设置为: ${:import(org.apache.logging.log4j.LogManager,org.apache.logging.log4j.Logger)} private static final Logger LOG = LogManager.getLogger(${enclosure_type}.class);
【解决方案2】:

这里有一些额外的模板:Link I - Link II

我喜欢这个:

读取文件

 ${:import(java.io.BufferedReader,  
           java.io.FileNotFoundException,  
           java.io.FileReader,  
           java.io.IOException)}  
 BufferedReader in = null;  
 try {  
    in = new BufferedReader(new FileReader(${fileName}));  
    String 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} 

更新:此模板的 Java 7 版本是:

${: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(String)}),
                                                 Charset.forName("UTF-8"))) {
    String line = null;
    while ((line = in.readLine()) != null) {
        ${cursor}
    }
} catch (IOException e) {
    // ${todo}: handle exception
}

【讨论】:

  • 我认为这是一种方法的用途:)
  • Err 我认为你错过了重点......说我实际上不知道你的意思是什么......这是关于代码生成而不是模块化......
  • 我认为关键是在模板中添加这么多代码是一种非常常见的剪切和粘贴编程。
  • 是的,您应该使用实用程序方法来读取文件,而不是粘贴代码块。自己写一个方法,或者使用 Apache commons-io IOUtils。尽管如此,如果您使用不同的类路径创建大量一次性项目,那么在实用程序类中添加 JAR 或链接只是为了读取文件可能会很痛苦。有时您只需要编写一些一次性代码来读取文件,然后继续您的生活。
  • 在 Java 7 中,首选 StandardCharsets.UTF_8 而不是 Charset.forName("UTF-8")
【解决方案3】:

格式化字符串

MessageFormat - 用 MessageFormat 包围所选内容。

 ${:import(java.text.MessageFormat)} 
 MessageFormat.format(${word_selection}, ${cursor})

这让我可以将光标移动到一个字符串,将选择扩展到整个字符串(Shift-Alt-Up),然后按两次 Ctrl-Space。

锁定选择

lock - 用 try finally lock 包围选定的行。假设存在一个锁变量。

${lock}.acquire();
try {
    ${line_selection}
    ${cursor}
} finally {
    ${lock}.release();
}

NB ${line_selection} 模板显示在 Surround With 菜单中 (Alt-Shift-Z)。

【讨论】:

【解决方案4】:

我知道我在踢一个死帖,但为了完整起见想分享这个:

一个正确版本的单例生成模板,克服了有缺陷的双重检查锁定设计(在上面讨论并在其他地方提到)

单例创建模板: 将此命名为createsingleton

static enum Singleton {
    INSTANCE;

    private static final ${enclosing_type} singleton = new ${enclosing_type}();

    public ${enclosing_type} getSingleton() {
        return singleton;
    }
}
${cursor}


要访问使用上面生成的单例:

单例参考模板: 将此命名为getsingleton

${type} ${newName} = ${type}.Singleton.INSTANCE.getSingleton();

【讨论】:

  • 它还没有死,它是社区 wiki,因此在找到模板时添加更多模板是有意义的。在其他任何地方都没有真正全面的集合......
  • 乔恩,之前的帖子和我的帖子之间的时间差将近 8 个月,这就是不得不这样引用的原因。我不能说它比你的评论更好:)
  • 当我创建它作为类的一部分(类中的嵌套枚举)时,我得到的类名称为${enclosing_type} - 预期?
  • @Mr_and_Mrs_D,我认为这就是重点。您将获得放置此模板的类的单例实例。现在您需要做的就是将封闭类型构造函数设为私有并拥有一个非常安全的单例生成器。
  • 如果你想用它来创建一个枚举,使用${primary_type_name} 例子:public enum ${primary_type_name} { INSTANCE; private ${return_type} ${name} = new ${return_type}(); public ${return_type} ${getName}(${}) { return ${name}; } ${cursor} }
【解决方案5】:

附加代码 sn-p 以迭代 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<String, String> entry : properties.entrySet())
{
    String key = entry.getKey();
    String value = entry.getValue();
    |
}

【讨论】:

  • 就像你的图片一样,它向我展示了你可以在${} 中使用一个变量,而不是${cursor},它可以在字段之间启用“标签迭代”。谢谢。
【解决方案6】:

对于log,在成员变量中添加一个有用的小曲子。

private static Log log = LogFactory.getLog(${enclosing_type}.class);

【讨论】:

  • 手动写入日志文件:${:import(java.io.PrintWriter, java.io.BufferedWriter, java.io.FileWriter)} try { PrintWriter out = new PrintWriter(new BufferedWriter (new FileWriter(${logFile:var(String)}, true))); out.println(${logLine:var(String)}${cursor}); out.close(); } catch (IOException e) { /* TODO: 异常处理 */ e.printStackTrace(); }
【解决方案7】:

使用 Mockito 创建一个模拟(在“Java 语句”上下文中):

${:importStatic('org.mockito.Mockito.mock')}${Type} ${mockName} = mock(${Type}.class);

在“Java 类型成员”中:

${:import(org.mockito.Mock)}@Mock
${Type} ${mockName};

模拟一个 void 方法抛出异常:

${:import(org.mockito.invocation.InvocationOnMock,org.mockito.stubbing.Answer)}
doThrow(${RuntimeException}.class).when(${mock:localVar}).${mockedMethod}(${args});

模拟一个 void 方法来做某事:

${:import(org.mockito.invocation.InvocationOnMock,org.mockito.stubbing.Answer)}doAnswer(new Answer<Object>() {
public Object answer(InvocationOnMock invocation) throws Throwable {
    Object arg1 = invocation.getArguments()[0];
    return null;
}
}).when(${mock:localVar}).${mockedMethod}(${args});

验证只调用一次的模拟方法:

${:importStatic(org.mockito.Mockito.verify,org.mockito.Mockito.times)}
verify(${mock:localVar}, times(1)).${mockMethod}(${args});

验证模拟方法从未被调用:

${:importStatic(org.mockito.Mockito.verify,org.mockito.Mockito.never)}verify(${mock:localVar}, never()).${mockMethod}(${args});

使用 Google Guava 的新链表(hashset 和 hashmap 类似):

${import:import(java.util.List,com.google.common.collect.Lists)}List<${T}> ${newName} = Lists.newLinkedList();

我还使用了一个巨大的模板来生成一个测试类。这是每个有兴趣的人都应该自定义的简短片段:

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

【讨论】:

  • 我很好奇:你为什么需要模拟记录器?
  • 您可以验证是否调用了模拟记录器以防捕获到异常(失败场景)。如果您不打算重新抛出它但想要断言它不会被默默忽略,这将非常有用。
【解决方案8】:

空检查!

if( ${word_selection} != null ){
    ${cursor}
}

if( ${word_selection} == null ){
    ${cursor}
}

【讨论】:

  • Guava 中的 PreConditions.checkNotNull(...) 方法是一种非常易读的替代方法(尤其是静态导入)
  • 最佳做法是在检查非空之前先检查空 (== null)。
【解决方案9】:

我心爱的人之一是 foreach

for (${iterable_type} ${iterable_element} : ${iterable}) {
    ${cursor}
}

还有 traceout,因为我经常使用它进行跟踪:

System.out.println("${enclosing_type}.${enclosing_method}()");

我刚刚想到另一个,有一天在互联网上找到了它,const

private static final ${type} ${name} = new ${type} ${cursor};

【讨论】:

  • foreach 在 Eclipse 中可用作标准代码辅助,我看不到您的模板对标准版本有任何附加作用
  • 对了,sysout是一个很有创意的模板。问题是关于我们正在使用的有用模板。
  • 您的 traceout 已在 Eclipse 中作为 systrace 提供。
  • 很好,由于这个问题,我想相信它现在出现在 Eclipse 中。
  • const 可作为标准代码辅助作为 static_final 使用(但不确定何时添加)
【解决方案10】:

关于 sysout 的一点提示——我喜欢将它重命名为“sop”。 java 库中没有其他内容以“sop”开头,因此您可以快速键入“sop”并插入它。

【讨论】:

  • 默认情况下,只需键入 syso 将与 sysout 执行相同的操作。
  • 用 sop 击败你 25%,不过...... ;)
  • 由于 Eclipse Mars 在快捷键 "syso" + Ctrl + Space 上有一个糟糕的倒退:它将列出一些具有字符 s、y、s 和o 在他们的名字中(由于新的 CamelCase 发现)。因此,现在您必须从列表中另外选择 sysout 并按 Return。
【解决方案11】:

在当前范围内抛出带有变量的 IllegalArgumentException (illarg):

throw new IllegalArgumentException(${var});

更好

throw new IllegalArgumentException("Invalid ${var} " + ${var});  

【讨论】:

    【解决方案12】:

    对于代码生产没有什么花哨的 - 但对代码审查非常有用

    我的模板 coderev low/med/high 执行以下操作

    /**
     * Code Review: Low Importance
     * 
     *
     * TODO: Insert problem with code here 
     *
     */
    

    然后在“任务”视图中 - 将显示我想在会议期间提出的所有代码审查 cmets。

    【讨论】:

      【解决方案13】:

      更多模板here

      包括:

      • 根据特定日期创建日期对象
      • 创建一个新的泛型 ArrayList
      • 记录器设置
      • 指定级别的日志
      • 创建一个新的通用 HashMap
      • 遍历地图,打印键和值
      • 使用 SimpleDateFormat 解析时间
      • 逐行读取文件
      • 记录并重新抛出捕获的异常
      • 打印代码块的执行时间
      • 创建周期性定时器
      • 将字符串写入文件

      【讨论】:

      • 添加了回路机链接
      【解决方案14】:

      slf4j 日志记录

      ${imp:import(org.slf4j.Logger,org.slf4j.LoggerFactory)}
      
      private static final Logger LOGGER = LoggerFactory
          .getLogger(${enclosing_type}.class);
      

      【讨论】:

        【解决方案15】:

        Bean 属性

        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(String propertyName, PropertyChangeListener listener) {
          ${propertyChangeSupport}.addPropertyChangeListener(propertyName, listener);
        }
        
        public void removePropertyChangeListener(PropertyChangeListener listener) {
          ${propertyChangeSupport}.removePropertyChangeListener(listener);
        }
        
        public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
          ${propertyChangeSupport}.removePropertyChangeListener(propertyName, listener);
        }
        

        【讨论】:

          【解决方案16】:

          在 Java 7 之后,设置需要(或更喜欢)对封闭类进行静态引用的记录器的好方法是使用新引入的 MethodHandles API 在静态上下文中获取运行时类。

          SLF4J 的一个示例 sn-p 是:

          private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
          

          除了在任何 IDE 中作为一个简单的 sn-p 之外,如果您将某些功能重构到另一个类中,它也不会那么脆弱,因为您不会不小心携带类名。

          【讨论】:

            【解决方案17】:

            在 GUI 线程上调用代码

            我将以下模板绑定到快捷方式slater 以在 GUI 线程上快速调度代码。

            ${:import(javax.swing.SwingUtilities)}
            SwingUtilities.invokeLater(new Runnable() {      
                  @Override
                  public void run() {
                    ${cursor}
                  }
                });
            

            【讨论】:

              【解决方案18】:

              在使用代码进行测试时,我有时会错过删除一些 syso 的机会。所以我给自己做了一个模板,叫做syt

              System.out.println(${word_selection}${});//${todo}:remove${cursor}
              

              在编译之前,我总是检查我的 TODO,并且永远不会忘记再次删除 System.out。

              【讨论】:

                【解决方案19】:

                strf -&gt; String.format("msg", args) 非常简单,但节省了一点打字时间。

                String.format("${cursor}",)
                

                【讨论】:

                • 我使用 String.format("${string}",${objects}),因为 Eclipse 允许我在字符串和对象列表之间切换。
                • 我用的是这个版本:String.format(${word_selection}${},)${cursor},先选择一个字符串然后用'sf'就可以了。添加 %s 等等...
                【解决方案20】:

                从当前显示中获取 SWT 颜色:

                Display.getCurrent().getSystemColor(SWT.COLOR_${cursor})
                

                用syncexec环绕

                PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable(){
                    public void run(){
                        ${line_selection}${cursor}
                    }
                });
                

                使用单例设计模式:

                /**
                 * 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;
                }
                

                【讨论】:

                • 简短说明 - 据被称为 Joshua Bloch 的大师所说,使用枚举应该是在 Java 中创建单例的首选方法。
                • 嗨 Pablojim,自从我发布了这个模板后,我开始阅读 Effective Java,并将我的单例实现更改为枚举。尽管如此,我还是没有找到让模板生成枚举并因此修改类声明的方法。你有这个模板吗?谢谢马努
                • 仅供参考:这是枚举单例模式electrotek.wordpress.com/2008/08/06/…。我不是特别喜欢它,但是我没有很多单身人士。将其转换为 Java 模板很容易。
                • 对于枚举方法,我希望你所有的单例作为 Comparable、Serializable 对象都有意义,因为很多单例都没有(他想知道为什么这种“......方法还没有被广泛使用采用”——因为可比性和序列化对于某些单例类没有意义!)
                • 可序列化?是的。考虑使用对您的 Singleton 的引用对 Object 进行序列化。如果它不是可序列化的,那么您可能会遇到 NPE。如果是(并且您没有添加方法来覆盖默认的反序列化),那么您可能会获得“Singleton”的另一个实例。
                【解决方案21】:

                还有一个equalsbuilder、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);
                }
                

                【讨论】:

                • 对于没有反思的解决方案,请参阅下面link的答案@
                【解决方案22】:

                记录器声明的模板很棒。

                我还为我经常使用的日志级别创建了 linfo、ldebug、lwarn、lerror。

                错误:

                logger.error(${word_selection}${});${cursor}
                

                【讨论】:

                  【解决方案23】:

                  为事件创建一切

                  由于在 Java 中创建事件有点麻烦——所有这些接口、方法和只为一个事件编写的东西——我制作了一个简单的模板来创建一个事件所需的一切。

                  ${: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);
                      }
                  }
                  

                  如果您有共享单个EventObject 的事件,只需删除模板插入的自定义事件并更改raise___()on____() 的相应部分。

                  我使用泛型接口和泛型类编写了一个漂亮、小巧、优雅的事件机制,但由于 Java 处理泛型的方式,它无法工作。 =(

                  编辑: 1) 我遇到了线程在事件发生时添加/删除侦听器的问题。 List 在使用时无法修改,所以我添加了synchronized 块正在访问或使用侦听器列表的位置,并锁定列表本身。

                  【讨论】:

                  • 在处于锁定状态(同步或其他方式)时发送事件是等待发生的死锁。在这种情况下,最好在同步块中复制侦听器并迭代新列表。
                  • 使用ConcurrentLinkedQueue。它不需要锁定,因为它有一个弱一致的迭代器,它从不抛出 ConcurrentModificationException。
                  【解决方案24】:

                  插入测试方法 should-given-when-then

                  我最近在与一位非常优秀的开发人员和朋友结对编程时看到了一个与此类似的版本,我认为它可能是这个列表的一个很好的补充。

                  此模板将按​​照 cmets 上 behavior-driven development (BDD) 范式中的 Given - When - Then approach 在类上创建一个新的测试方法,作为构建代码的指南。它将以“should”开头的方法名称,并让您用测试方法职责的最佳描述替换虚拟方法名称“CheckThisAndThat”的其余部分。填写名称后,TAB 会直接将您带到// Given section,因此您可以开始输入您的前提条件。

                  我将它映射到三个字母“tst”,并带有描述“Test methods should-given-when-then”;)

                  我希望你发现它和我看到它时一样有用:

                  @Test
                  public void should${CheckThisAndThat}() {
                      Assert.fail("Not yet implemented");
                      // Given
                      ${cursor}
                  
                      // When
                  
                  
                      // Then
                  
                  }${:import(org.junit.Test, org.junit.Assert)}
                  

                  【讨论】:

                  • 我喜欢那个模板。我添加了一个“抛出异常”以进一步减轻测试的舒适度。
                  • 我喜欢 BDD 范式。非常好的模板。请注意:您非常好的开发人员和朋友已经走了!
                  【解决方案25】:

                  弹簧注射

                  我知道这对游戏来说有点晚了,但这是我在课堂上用于 Spring Injection 的一个:

                  ${: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};
                  }
                  

                  【讨论】:

                    【解决方案26】:

                    这是一个不可实例化类的构造函数:

                    // Suppress default constructor for noninstantiability
                    @SuppressWarnings("unused")
                    private ${enclosing_type}() {
                        throw new AssertionError();
                    }
                    

                    这个是针对自定义异常的:

                    /**
                     * ${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(String) 
                         */
                        public ${Name}Exception(String message) {
                            super(message);         
                        }
                    
                        /**
                         * @see Exception#Exception(Throwable)
                         */
                        public ${Name}Exception(Throwable cause) {
                            super(cause);           
                        }
                    
                        /**
                         * @see Exception#Exception(String, Throwable)
                         */
                        public ${Name}Exception(String message, Throwable cause) {
                            super(message, cause);
                        }
                    }
                    

                    【讨论】:

                      【解决方案27】:

                      我喜欢这样生成的班级评论:

                      /**
                       * I... 
                       * 
                       * $Id$
                       */
                      

                      “我...”立即鼓励开发人员描述该类的功能。我似乎确实改善了无证类的问题。

                      当然 $Id$ 是一个有用的 CVS 关键字。

                      【讨论】:

                        【解决方案28】:

                        我已经大量使用这些 sn-ps,寻找 null 值和空字符串。

                        我使用“参数测试”模板作为方法中的第一个代码来检查接收到的参数。

                        testNullArgument

                        if (${varName} == null) {
                            throw new NullPointerException(
                                "Illegal argument. The argument cannot be null: ${varName}");
                        }
                        

                        您可能希望更改异常消息以符合您公司或项目的标准。但是,我确实建议您使用一些包含违规参数名称的消息。否则,您的方法的调用者将不得不查看代码以了解出了什么问题。 (没有消息的NullPointerException 会产生一个异常,带有相当荒谬的消息“null”)。

                        testNullOrEmptyStringArgument

                        if (${varName} == null) {
                            throw new NullPointerException(
                                "Illegal argument. The argument cannot be null: ${varName}");
                        }
                        ${varName} = ${varName}.trim();
                        if (${varName}.isEmpty()) {
                            throw new IllegalArgumentException(
                                "Illegal argument. The argument cannot be an empty string: ${varName}");
                        }
                        

                        您还可以重用上面的空值检查模板并实现此 sn-p 以仅检查空字符串。然后,您将使用这两个模板来生成上述代码。

                        然而,上面的模板有一个问题,如果 in 参数是最终的,您将不得不修改生成的代码(${varName} = ${varName}.trim() 将失败)。

                        如果您使用大量最终参数并希望检查空字符串,但又不必将它们作为代码的一部分进行修剪,则可以改为:

                        if (${varName} == null) {
                            throw new NullPointerException(
                                "Illegal argument. The argument cannot be null: ${varName}");
                        }
                        if (${varName}.trim().isEmpty()) {
                            throw new IllegalArgumentException(
                                "Illegal argument. The argument cannot be an empty string: ${varName}");
                        }
                        

                        testNullFieldState

                        我还创建了一些 sn-ps 来检查未作为参数发送的变量(最大的区别是异常类型,现在改为 IllegalStateException)。

                        if (${varName} == null) {
                            throw new IllegalStateException(
                                "Illegal state. The variable or class field cannot be null: ${varName}");
                        }
                        

                        testNullOrEmptyStringFieldState

                        if (${varName} == null) {
                            throw new IllegalStateException(
                                "Illegal state. The variable or class field cannot be null: ${varName}");
                        }
                        ${varName} = ${varName}.trim();
                        if (${varName}.isEmpty()) {
                            throw new IllegalStateException(
                                "Illegal state. The variable or class field " +
                                    "cannot be an empty string: ${varName}");
                        }
                        

                        testArgument

                        这是测试变量的通用模板。我花了几年的时间才真正学会欣赏这个,现在我经常使用它(当然要结合上面的模板!)

                        if (!(${varName} ${testExpression})) {
                            throw new IllegalArgumentException(
                                "Illegal argument. The argument ${varName} (" + ${varName} + ") " +
                                "did not pass the test: ${varName} ${testExpression}");
                        }
                        

                        您输入一个变量名称或一个返回值的条件,后跟一个操作数(“==”、“”等)和另一个值或变量,如果测试失败,结果代码将抛出一个 IllegalArgumentException。

                        if 子句稍微复杂,整个表达式用“!()”包裹的原因是为了可以在异常消息中重用测试条件。

                        也许这会让同事感到困惑,但前提是他们必须查看代码,如果您抛出此类异常,他们可能不必查看...

                        这是一个数组示例:

                        public void copy(String[] from, String[] 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");
                            }
                        }
                        

                        您可以通过调用模板并输入“from.length”[TAB]“== to.length”来获得此结果。

                        结果比“ArrayIndexOutOfBoundsException”或类似的更有趣,实际上可能让您的用户有机会找出问题。

                        享受吧!

                        【讨论】:

                          【解决方案29】:

                          我将它用于 MessageFormat(使用 Java 1.4)。这样我确信在进行国际化时我没有难以提取的连接

                          i18n

                          String msg = "${message}";
                          Object[] params = {${params}};
                          MessageFormat.format(msg, params);
                          

                          也用于记录:

                          日志

                          if(logger.isDebugEnabled()){
                            String msg = "${message}"; //NLS-1
                            Object[] params = {${params}};
                            logger.debug(MessageFormat.format(msg, params));
                          }
                          

                          【讨论】:

                            【解决方案30】:

                            我最喜欢的几个是...

                            1:Javadoc,插入有关该方法为Spring对象注入方法的文档。

                             Method to set the <code>I${enclosing_type}</code> implementation that this class will use.
                            * 
                            * @param ${enclosing_method_arguments}<code>I${enclosing_type}</code> instance 
                            

                            2:调试窗口,创建一个 FileOutputStream 并将缓冲区的内容写入文件。 用于将缓冲区与过去的运行进行比较(使用 BeyondCompare),或者由于缓冲区太大而无法查看缓冲区的内容(通过检查)...

                            java.io.FileOutputStream fos = new java.io.FileOutputStream( new java.io.File("c:\\x.x"));
                            fos.write(buffer.toString().getBytes());
                            fos.flush();
                            fos.close();
                            

                            【讨论】:

                              猜你喜欢
                              • 2012-08-06
                              • 1970-01-01
                              • 1970-01-01
                              • 2012-10-30
                              • 1970-01-01
                              • 2012-02-03
                              • 2011-01-06
                              • 2010-11-14
                              • 1970-01-01
                              相关资源
                              最近更新 更多