RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 598005
Accepted
Cenzor
Cenzor
Asked:2020-12-01 13:12:00 +0000 UTC2020-12-01 13:12:00 +0000 UTC 2020-12-01 13:12:00 +0000 UTC

实际中应该在什么情况下使用反射和注解?

  • 772

帮我理解。

例如,反射的一个特定定义是这样说的:“反射是一种工具,通过它你可以找到关于一个类的所有信息:方法名、参数、字段、注释……”。

作为一个初学者,我有一个合理的疑问,如果类、方法、字段等不存在,为什么还需要查找这些信息?我自己写,知道他们的一切?

我知道反射没有用于我的课程等,但是我找不到一个初学者可以理解的真实例子:在什么情况下我会面临我不知道课程名称的事实、方法等?

与注解相同:“……一个允许您在源文件中嵌入帮助信息的工具……”。好吧,我会把它建进去,但利润是多少,我最终会借助它得到什么?注释的存在会给开发人员带来什么好处?他们如何让生活更轻松?

java
  • 2 2 个回答
  • 10 Views

2 个回答

  • Voted
  1. Best Answer
    Mark Shevchenko
    2020-12-01T14:14:48Z2020-12-01T14:14:48Z

    反射和注释使您能够解决原本可以通过手动单调编码或代码生成来解决的问题。

    而且,当然,当它们被使用时,它们并不适用于特定的类,而是有一定的余量,甚至适用于您将来编写的那些类。它们通常用于在项目之间徘徊的库代码中,因此对这些项目的类一无所知。

    几个具体的例子:

    休眠注解

    Hibernate 是一个 ORM,即一个用于方便地将数据库映射到目标代码的库。通常在基础代码和 Java 代码中使用不同的命名约定。为了让 Hibernate 了解将哪个字段复制到哪里,使用了注释。对于一张桌子:

    create table EMPLOYEE (
      id INT NOT NULL auto_increment,
      first_name VARCHAR(20) default NULL,
      last_name  VARCHAR(20) default NULL,
      salary     INT  default NULL,
      PRIMARY KEY (id)
    );
    

    可以应用注释:

    @Entity
    @Table(name = "EMPLOYEE")
    public class Employee {
      @Id @GeneratedValue
      @Column(name = "id")
      private int id;
    
      @Column(name = "first_name")
      private String firstName;
    
      @Column(name = "last_name")
      private String lastName;
    
      @Column(name = "salary")
      private int salary;  
    
      public Employee() {}
      public int getId() {
        return id;
      }
      public void setId( int id ) {
        this.id = id;
      }
      public String getFirstName() {
        return firstName;
      }
      public void setFirstName( String first_name ) {
        this.firstName = first_name;
      }
      public String getLastName() {
        return lastName;
      }
      public void setLastName( String last_name ) {
        this.lastName = last_name;
      }
      public int getSalary() {
        return salary;
      }
      public void setSalary( int salary ) {
        this.salary = salary;
      }
    }
    

    该示例取自此处。简而言之,这里发生了什么:在数据库中,该字段被称为,例如,first_name在 Java 代码中 - firstName。多亏了注解,当从数据库中加载记录到一个对象中时,Employee该库将独立分散所有字段。

    Java编译器

    编译器还使用注释进行额外检查或更改其在各个方法中的设置。见注解@Override和@SuppressWarnings。

    Android注解

    http://androidannotations.org/项目允许您通过实现常见任务并将它们包装在注释中来极大地简化 Android 代码的开发。这只是将在不熟悉的项目中工作的库代码的一个很好的例子。自然地,反射被积极地用于实现这段代码。“注释前”和“注释后”的示例直接在上面链接的主页上给出。

    面向方面编程

    我不会写太多关于他的内容,因为这个话题很大,对于初学者来说可能不是很有必要。但总的来说,AOP 就是这样。例如,您可以编写自己的类,然后负责检查权限,就像管理员可以删除记录,但普通用户不能。

    使用经典方法,您必须对大量现有类进行相同类型的更改,然后记得对新类进行更改。在 AOP 中,您可以简单地提出注释@Administrator,并将它们放在所需的类和方法上。这也是单调的,但还是简单多了。@User@Moderator

    没有注释的反射

    反射的使用更为频繁,例如,在各种模板引擎和映射器中。模板引擎允许您使用像这样的电子邮件模板:

    Здравствуйте, %username%!
    
    Напоминаем Вам, что вы задолжали нам крупную сумму денег в размере %amount%
    рублей. Мы помним!
    
    С уважением,
      Коллекторское агентство «Солнышко»
    

    然后你将一个带有字段的类传递给模板引擎username,amount它会独立生成信件的文本。没有反思就无法完成这样的任务。

    结论

    总的来说,反射和注解可以让你摆脱所谓的monkey coding,即单调的底层编码。

    • 11
  2. Suvitruf - Andrei Apanasik
    2020-12-01T13:55:46Z2020-12-01T13:55:46Z

    1)依赖注入框架往往基于反射

    2) 按名称调用方法。假设您有一个方法名称作为输入,您可以这样调用它:

    Method method = foo.getClass().getMethod("myMethod", null);
    method.invoke(foo, null);
    

    3) 类实例化也是一样。我们是在Unity3d上做游戏,这里虽然是C#,但是本质没有变。我们有一堆法术。可用法术列表作为数组。我们需要按名称实例化所需的类。要么switch用 heap做一个大块case,要么只调用 1 种方法。

    4) 在反思的帮助下,如有必要,您可以触及课堂final领域protected。例如,当我使用 Android 时,我经常需要这样做。SDK 中的许多类字段是隐藏的,您只能通过反射来获取和更改它们。

    PS 但尽可能避免使用反射,因为它本质上非常慢

    • 7

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    如何停止编写糟糕的代码?

    • 3 个回答
  • Marko Smith

    onCreateView 方法重构

    • 1 个回答
  • Marko Smith

    通用还是非通用

    • 2 个回答
  • Marko Smith

    如何访问 jQuery 中的列

    • 1 个回答
  • Marko Smith

    *.tga 文件的组重命名(3620 个)

    • 1 个回答
  • Marko Smith

    内存分配列表C#

    • 1 个回答
  • Marko Smith

    常规赛适度贪婪

    • 1 个回答
  • Marko Smith

    如何制作自己的自动完成/自动更正?

    • 1 个回答
  • Marko Smith

    选择斐波那契数列

    • 2 个回答
  • Marko Smith

    所有 API 版本中的通用权限代码

    • 2 个回答
  • Martin Hope
    jfs *(星号)和 ** 双星号在 Python 中是什么意思? 2020-11-23 05:07:40 +0000 UTC
  • Martin Hope
    hwak 哪个孩子调用了父母的静态方法?还是不可能完成的任务? 2020-11-18 16:30:55 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    user207618 Codegolf——组合选择算法的实现 2020-10-23 18:46:29 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    Arch ArrayList 与 LinkedList 的区别? 2020-09-20 02:42:49 +0000 UTC
  • Martin Hope
    iluxa1810 哪个更正确使用:if () 或 try-catch? 2020-08-23 18:56:13 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5