modou
2009-03-14 01:46
浏览 269
已采纳

匿名类中如何传值出来呢?

先来看代码:
[code="java"]@Controller
public class T1 implements MethodInterceptor {

private Object obj;

@Autowired
private SimpleAsyncTaskExecutor task;

public Object invoke(final MethodInvocation mi) throws Throwable {  
    task.execute(new Runnable(){

        public void run() {
            try {
                obj = mi.proceed(); // 这里我需要把执行的结果传入到T1类,我定义了一个Object对象,可是值是传不出来的
            } catch (Throwable e) {
                e.printStackTrace();
            }

        }
    });

    return obj; // 刚才传的值这里要用
}

}[/code]

MethodInterceptor是我实现了spring中一个接口,关于aop的。
SimpleAsyncTaskExecutor是spring中的一个类,用于实现对并发的总数做限制的。
上面我写的有注释,内部类执行的值怎么才能传出来给T1类使用呢?
[b]问题补充:[/b]
@RednaxelaFX,非常感谢,按照你的方法,问题解决了:
[code="java"]@Controller
public class T1 implements MethodInterceptor {

@Autowired
private SimpleAsyncTaskExecutor executor;

public Object invoke(final MethodInvocation mi) throws Throwable {

    FutureTask<Object> task = new FutureTask<Object>(new Callable<Object>() {   
        public Object call() {   
            try {
                return mi.proceed();
            } catch (Throwable e) {
                return null;
            }   
        }
    });  

    executor.execute(task);

    return task.get();
}

}[/code]

  • 写回答
  • 好问题 提建议
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • rednaxelafx 2009-03-14 02:49
    已采纳

    Java的匿名内部类的使用限制是它只能访问外围类中的final成员,但没关系,Java中final对引用类型的语义是“这个引用在初始化之后不能用于指向别的对象”,至于被指向的对象的状态怎么变它不关心。所以随便用什么容器都能够从匿名内部类中返回值:
    [code="java"]interface IFoo {
    void foo();
    }

    public class Test {
    private final Object[] arr = new Object[1];

    private void bar() {
    (new IFoo() {

    public void foo() {
    arr[0] = "result";
    }
    }).foo();
    }

    public static void main(String[] args) throws Exception {
    Test t = new Test();
    t.bar();
    System.out.println(t.arr[0]); // result
    }
    }[/code]

    不过上面这段代码在多线程条件下明显很糟糕。不放心的话就用java.util.concurrent包里的容器:
    [code="java"]import java.util.concurrent.*;

    interface IFoo {
    void foo();
    }

    public class Test {
    private final BlockingQueue result = new ArrayBlockingQueue(1);

    private void bar() {
    (new IFoo() {

    public void foo() {
    try {
    result.put("result");
    } catch (Exception e) {
    }
    }
    }).foo();
    }

    public static void main(String[] args) throws Exception {
    Test t = new Test();
    t.bar();
    System.out.println(t.result.take()); // result
    }
    }[/code]
    take会在还没有足够数据的时候block住。

    不过要是能用Future系的接口就更好了。于是或许你不应用execute()方法,而应该用submit()方法来配合Callable接口使用。Runnable()本来就不适合用于返回值,Callable就是为了解决这个问题而出现的。类似这样
    [code="java"]import java.util.concurrent.*;

    @Controller
    public class T1 implements MethodInterceptor {
    @Autowired
    private SimpleAsyncTaskExecutor executor;

    public Object invoke(final MethodInvocation mi) throws Throwable {
        FutureTask<Object> task = new FutureTask(new Callable<Object>() {
            public Object call() {
                return mi.proceed();
            }
        });
        executor.sumbit(task);
    
        Object result = null;
        try {
            result = task.get();
        } catch (Exception e) {
            e.printStackTrace();
        }
    
        return result;
    }
    

    }[/code]
    具体怎么用还得看你自己的需要了。很明显你没把所有代码贴出来,或许有些别的地方要注意的,呵呵~

    已采纳该答案
    评论
    解决 无用
    打赏 举报
  • rednaxelafx 2009-03-14 02:52

    呃,刚才敲代码的时候手滑了,new FutureTask后面忘了。不过其实都是的话写不写都一样,反正类型擦除之后也就是Object……Java编译器对泛型的警告直接无视就是了 :-p

    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题