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

时间:2017-07-06 18:46:36

标签: java multithreading

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

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

例如,我需要访问Material对象,如果它从属于隐式线程对象的insertMaterial()方法中传递给run()方法args,而不是创建{ {1}}线程对象内的对象。

1 个答案:

答案 0 :(得分:0)

JLS 8.1.3. Inner Classes and Enclosing Instances中:

  

当一个内部类(其声明不在静态中发生)   context)指的是作为a的成员的实例变量   词汇封闭类,词汇对应的变量   使用封闭实例。

     

使用了任何局部变量,形式参数或异常参数但是   未在内部类中声明必须声明为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的变量被认为是有效的最终

     
      
  • 未宣布为最终版。

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

  •   
  • 它永远不会作为前缀或后缀增量的操作数或   减少运营商。

  •   

JLS 4.12.4. final Variables