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
变量或封闭类成员
/*
* 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感谢你的有效的最终建议。
建议:我会更新答案。