繁体   English   中英

如何在匿名内部类中使用外部变量

[英]How to use an outer variable in an anonymous inner class

如何从方法内部创建的隐式对象内部访问外部变量?

public void insertMaterial() {

new Thread(){

  public void run(){
    com.ssn.acx.api.configuration.ParameterSet ps = com.ssn.acx.api.ACXObjectFactory.getConfigurationFactory().getLocalConfiguration().getParameterSet(com.ssn.acx.api.persistence.ACXPersistenceFactory.CFG_DEFAULT);
    com.ssn.acx.api.persistence.ACXPersistenceFactory factory = com.ssn.acx.api.ACXObjectFactory.getPersistenceFactory(ps);
    com.ssn.acx.api.persistence.ACXPersistenceSession session = factory.openSession();
    com.ssn.acx.api.common.transaction.ACXTransaction tx = null;
    WMSMaterial mat = null;

    try {
      tx = session.beginTransaction("InsertMaterial");                    

      mat = new WMSMaterial("101", "Baby Lotion");
      session.getPersistenceSession().insert(mat);          

      mat = new WMSMaterial("102", "Bubble Gum");
      session.getPersistenceSession().insert(mat); 

      mat = new WMSMaterial("103", "Soda");
      session.getPersistenceSession().insert(mat);  

      tx.commit();

    } finally { if (tx != null && !tx.closed()) { tx.rollback(); } session.close(); }//end of try-catch-finally block

  }//end of run method

}.start(); //end of Thread Object creation


}   //end of insertMaterial method

例如,如果我insertMaterial()隐式线程对象的run()方法内部将Material对象传递给insertMaterial()方法args,而不是在线程对象内部创建Material对象,则我需要访问它。

JLS 8.1.3中。 内部类和封闭实例

当内部类(其声明不在静态上下文中发生)引用一个实例变量时,该实例变量是词法包围类的成员,则使用相应的词法包围实例的变量。

使用的但未在内部类中声明的任何局部变量,形式参数或异常参数必须声明为final。

这意味着您只能在匿名内部类中使用外部 final变量或封闭类成员。

/*
 * I suggest this solution, but not this approach, 
 * please be careful with multi-threading programming. :)
 */

// [...]
// private List<WMSMaterial> listMaterials; // or using a class member
// [...]
public void insertMaterial(final List<WMSMaterial> listMaterials) {

new Thread(){

  public void run(){
    com.ssn.acx.api.configuration.ParameterSet ps = com.ssn.acx.api.ACXObjectFactory.getConfigurationFactory().getLocalConfiguration().getParameterSet(com.ssn.acx.api.persistence.ACXPersistenceFactory.CFG_DEFAULT);
    com.ssn.acx.api.persistence.ACXPersistenceFactory factory = com.ssn.acx.api.ACXObjectFactory.getPersistenceFactory(ps);
    com.ssn.acx.api.persistence.ACXPersistenceSession session = factory.openSession();
    com.ssn.acx.api.common.transaction.ACXTransaction tx = null;

    try {
      tx = session.beginTransaction("InsertMaterial");                    

      for (WMSMaterial material : listMaterials) {
          session.getPersistenceSession().insert(material);
      }

      tx.commit();

    } finally { if (tx != null && !tx.closed()) { tx.rollback(); } session.close(); }//end of try-catch-finally block

  }//end of run method

}.start(); //end of Thread Object creation


}   //end of insertMaterial method

[更新]

正如@AndyThomas在评论中指出的那样,Java 8实际上具有final变量 ,您无需显式将变量标记为final

某些未声明为final的变量实际上被认为是final

  • 它不是最终的。

  • 它永远不会出现在赋值表达式的左侧。 (请注意,包含初始化程序的局部变量声明符不是赋值表达式。)

  • 它永远不会作为前缀或后缀递增或递减运算符的操作数出现。

JLS 4.12.4。 最终变量

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM