有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java在常用的操作方法中使用反射可以吗?

我听说Java反射比常规方法调用慢。但显然,在编程中需要动态调用方法。 我见过spring和hibernate等框架使用反射来调用getter/setter和调用web方法

Spring mvc调用控制器方法:

at com.sampleapp.admin.controller.LoginController.login(LoginController.java:49)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:806)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:729)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)

休眠创建新实例:

at com.sampleapp.orm.model.Publisher.<init>(Publisher.java:61)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at org.hibernate.engine.internal.UnsavedValueFactory.instantiate(UnsavedValueFactory.java:46)
    at org.hibernate.engine.internal.UnsavedValueFactory.getUnsavedIdentifierValue(UnsavedValueFactory.java:68)
    at org.hibernate.tuple.PropertyFactory.buildIdentifierProperty(PropertyFactory.java:75)
    at org.hibernate.tuple.entity.EntityMetamodel.<init>(EntityMetamodel.java:145)
    at org.hibernate.persister.entity.AbstractEntityPersister.<init>(AbstractEntityPersister.java:505)
    at org.hibernate.persister.entity.SingleTableEntityPersister.<init>(SingleTableEntityPersister.java:146)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at org.hibernate.persister.internal.PersisterFactoryImpl.create(PersisterFactoryImpl.java:163)
    at org.hibernate.persister.internal.PersisterFactoryImpl.createEntityPersister(PersisterFactoryImpl.java:135)
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:381)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1746)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1784)

因此,这意味着即使是成熟的框架也在定期使用反射。 那么在我们的代码中使用反射好吗?它会对性能产生显著影响吗?(如果我的应用程序预计每秒处理的请求数比较大)或者我应该一直寻找诸如“字节码操作”之类的替代方案吗


共 (1) 个答案

  1. # 1 楼答案

    试图回答你(非常广泛)的问题:

    使用反射不是“好”的,它是一种你有时无法避免的邪恶。为什么它是邪恶的

    • 编译时检查不再适用。如果通过反射使用错误的参数数或错误的参数类型调用方法,编译器将不再拒绝您的调用,但在运行时会出现异常

    • 它使静态代码分析变得不可能,例如Eclipse的“调用层次结构”无法找到通过反射调用方法的位置

    • 这比直接通话慢

    对我来说,前两个原因很重要,这意味着您需要在质量保证方面投入更多精力,并且代码的可读性和可维护性较差(因为常用的工具不再有用)

    关于表现,在你真正遇到问题之前不要去想。不要落入“过早优化”的陷阱

    所以,如果没有其他方法来解决你的问题(请仔细想想),那就去反思吧。但要确保应对由此带来的质量和维护风险