Tom корректен в описании точно, что + делает оператор. Это создает временный файл StringBuilder
, добавляет части и заканчивается с toString()
.
Однако все ответы до сих пор игнорируют эффекты оптимизации времени выполнения HotSpot. А именно, эти временные операции распознаны как общий шаблон и заменяются более эффективным машинным кодом во времени выполнения.
@marcio: Вы создали микросравнительный тест ; с современной JVM это не допустимый способ представить код.
причина, оптимизация времени выполнения имеет значение, состоит в том, что многие из этих различий в коде - даже включая создание объекта - полностью отличаются, как только HotSpot начинается. Единственный способ знать наверняка представляет Ваш код на месте .
Наконец, все эти методы на самом деле невероятно быстры. Это могло бы быть случаем преждевременной оптимизации. Если у Вас есть код, который конкатенирует, представляет много в виде строки, способ получить максимальную скорость, вероятно, не имеет никакого отношения, какие операторы Вы выбираете и вместо этого алгоритм, который Вы используете!
Использовать отражение легко, просто аннотируйте метод с помощью @Audit, точно так же, как тестовые программы в JUnit:
public interface Login {
void login(String name, String password);
}
public class LoginImpl implements Login {
@Audit(handler = LoginHandler.class)
public void login(String name, String password) {
System.out.println("login");
}
}
@Audit определяется как:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Audit {
Class<? extends Handler> handler();
}
, где Handler:
interface Handler {
void handle();
}
class LoginHandler implements Handler {
public void handle() {
System.out.println("HANDLER CALLED!");
}
}
, а теперь реальный код:
public class LoginFactory {
private static class AuditInvocationHandler implements InvocationHandler {
private final Login realLogin;
public AuditInvocationHandler(Login realLogin) {
this.realLogin = realLogin;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Method realMethod = realLogin.getClass().getMethod(
method.getName(),
method.getParameterTypes());
Audit audit = realMethod.getAnnotation(Audit.class);
if (audit != null) {
audit.handler().newInstance().handle();
}
return method.invoke(realLogin, args);
}
}
public static Login createLogin() {
return (Login) Proxy.newProxyInstance(
LoginFactory.class.getClassLoader(),
new Class[]{Login.class},
new AuditInvocationHandler(new LoginImpl()));
}
}
@Test:
Login login = LoginFactory.createLogin();
login.login("user", "secret");
login.logout();
вывод:
HANDLER CALLED! login logout
Готово - используйте Spring или Guice .
Самостоятельное катание имеет смысл, если вы хотите знать, как работают колеса , или если вы думаете, что можете сделать что-то гораздо более легкое. Просто убедитесь, что оба верны, прежде чем браться за это.
Взгляните на методы перехвата в Guice: http://code.google.com/p/google-guice/wiki/AOP
Аналогичный подход должен работать с любая структура АОП.