简体   繁体   中英

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.

In 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.

It means you can only use an outside final variable or an enclosing class member in an anonymous inner class.

/*
 * 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 :

Certain variables that are not declared final are instead considered effectively 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. final Variables

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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