简体   繁体   English

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

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

How I can access an outer variable from inside an implicit object created inside a method? 如何从方法内部创建的隐式对象内部访问外部变量?

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

For example, I need to have access to Material object if it was passed to insertMaterial() method args from within the run() method which belongs to implicit thread object, instead of creating Material object inside the thread object. 例如,如果我insertMaterial()隐式线程对象的run()方法内部将Material对象传递给insertMaterial()方法args,而不是在线程对象内部创建Material对象,则我需要访问它。

In JLS 8.1.3. JLS 8.1.3中。 Inner Classes and Enclosing Instances : 内部类和封闭实例

When an inner class (whose declaration does not occur in a static context) refers to an instance variable that is a member of a lexically enclosing class, the variable of the corresponding lexically enclosing instance is used. 当内部类(其声明不在静态上下文中发生)引用一个实例变量时,该实例变量是词法包围类的成员,则使用相应的词法包围实例的变量。

Any local variable, formal parameter, or exception parameter used but not declared in an inner class must be declared final. 使用的但未在内部类中声明的任何局部变量,形式参数或异常参数必须声明为final。

It means you can only use an outside final variable or an enclosing class member in an anonymous inner class. 这意味着您只能在匿名内部类中使用外部 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

[Update] [更新]

As @AndyThomas points out in the comment, Java 8 has effectively final variable that you do not need to explicitly mark a variable as final : 正如@AndyThomas在评论中指出的那样,Java 8实际上具有final变量 ,您无需显式将变量标记为final

Certain variables that are not declared final are instead considered effectively final : 某些未声明为final的变量实际上被认为是final

  • It is not declared final. 它不是最终的。

  • It never occurs as the left hand side in an assignment expression . 它永远不会出现在赋值表达式的左侧。 (Note that the local variable declarator containing the initializer is not an assignment expression.) (请注意,包含初始化程序的局部变量声明符不是赋值表达式。)

  • It never occurs as the operand of a prefix or postfix increment or decrement operator. 它永远不会作为前缀或后缀递增或递减运算符的操作数出现。

JLS 4.12.4. JLS 4.12.4。 final Variables 最终变量

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

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