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

Java 如何在匿名内部类中使用外部变量,java,multithreading,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.

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

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
例如,如果从属于隐式线程对象的
run()
方法中将
Material
对象传递给
insertMaterial()
方法参数,我需要访问
Material
对象,而不是在线程对象中创建
Material
对象

In:

当一个内部类(其声明不出现在静态 上下文)引用的实例变量是 词法封闭类,对应词法封闭类的变量 使用封闭实例

使用的任何局部变量、形式参数或异常参数 内部类中未声明的必须声明为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
/*
*我建议这个解决方案,但不是这个方法,
*请小心多线程编程。:)
*/
// [...]
//私人列表材料;//或者使用类成员
// [...]
公共void insertMaterial(最终列表listMaterials){
新线程(){
公开募捐{
com.ssn.acx.api.configuration.ParameterSet ps=com.ssn.acx.api.ACXObjectFactory.getConfigurationFactory().getLocalConfiguration().getParameterSet(com.ssn.acx.api.persistence.ACXPersistenceFactory.CFG_默认值);
com.ssn.acx.api.persistence.ACXPersistenceFactory=com.ssn.acx.api.ACXObjectFactory.getPersistenceFactory(ps);
com.ssn.acx.api.persistence.ACXPersistenceSession=factory.openSession();
com.ssn.acx.api.common.transaction.ACXTransaction tx=null;
试一试{
tx=session.beginTransaction(“插入材料”);
对于(WMS物料:列表物料){
session.getPersistenceSession().insert(material);
}
tx.commit();
}finally{if(tx!=null&&!tx.closed()){tx.rollback();}session.close();}//try-catch-finally块结束
}//运行结束方法
}.start();//线程对象创建结束
}//insertMaterial方法的结尾

[更新]

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

某些未声明为最终变量的变量实际上被视为最终变量:

  • 这不是最终决定

  • 在赋值表达式中,它从不作为左侧出现 . (请注意,包含 初始值设定项不是赋值表达式。)

  • 它从不作为前缀或后缀增量或 减量运算符

在:

当一个内部类(其声明不出现在静态 上下文)引用的实例变量是 词法封闭类,对应词法封闭类的变量 使用封闭实例

使用的任何局部变量、形式参数或异常参数 内部类中未声明的必须声明为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
/*
*我建议这个解决方案,但不是这个方法,
*请小心多线程编程。:)
*/
// [...]
//私人列表材料;//或者使用类成员
// [...]
公共void insertMaterial(最终列表listMaterials){
新线程(){
公开募捐{
com.ssn.acx.api.configuration.ParameterSet ps=com.ssn.acx.api.ACXObjectFactory.getConfigurationFactory().getLocalConfiguration().getParameterSet(com.ssn.acx.api.persistence.ACXPersistenceFactory.CFG_默认值);
com.ssn.acx.api.persistence.ACXPersistenceFactory=com.ssn.acx.api.ACXObjectFactory.getPersistenceFactory(ps);
com.ssn.acx.api.persistence.ACXPersistenceSession=factory.openSession();
com.ssn.acx.api.common.transaction.ACXTransaction tx=null;
试一试{
tx=session.beginTransaction(“插入材料”);
对于(WMS物料:列表物料){
session.getPersistenceSession().insert(material);
}
tx.commit();
}finally{if(tx!=null&&!tx.closed()){tx.rollback();}session.close();}//try-catch-finally块结束
}//运行结束方法
}.start();//线程对象创建结束
}//insertMaterial方法的结尾

[更新]

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

某些未声明为最终变量的变量实际上被视为最终变量:

  • 这不是最终决定

  • 在赋值表达式中,它从不作为左侧出现 . (请注意,包含 初始值设定项不是赋值表达式。)

  • 它从不作为前缀或后缀增量或 减量运算符


使用
final
或类成员。或者,在Java 8中,确保变量是有效的final。也就是说,即使没有显式地将其标记为
final
,也不会对其进行任何更改。请使用
final
或类成员。或者,在Java 8中,请确保变量有效地为final。也就是说,即使您没有显式地将其标记为
final
,您也不会对其进行任何更改。@andythonas感谢您,+2表示
有效的final
建议:D我会更新答案。@Andythonas谢谢你,+2感谢你的
有效的最终建议。
建议:我会更新答案。