在编译时检查传递给方法的字符串参数是否具有@deprecated注释

如何解决在编译时检查传递给方法的字符串参数是否具有@deprecated注释

|| 我想验证是否不赞成使用传递给方法的字符串。例如。:
public class MyRepo
    @Deprecated
    private static final String OLD_PATH = \"old_path\";
    private static final String NEW_PATH = \"new_path\";

    //...

    public load(Node node){
        migrateProperty(node,OLD_PATH,NEW_PATH );

        //load the properties
        loadProperty(node,NEW_PATH);
    }

    //I want to validate that the String oldPath has the @Deprecated annotation
    public void migrateProperty(Node node,String oldPath,String newPath) {
        if(node.hasProperty(oldPath)){
            Property property = node.getProperty(oldPath);
            node.setProperty(newPath,(Value) property);
            property.remove();
        }
    }

    //I want to validate that the String path does not have the @Deprecated annotation
    public void loadProperty(Node node,String path) {
        //load the property from the node
    }
}
我能找到的最接近的是验证参数本身的注释。     

解决方法

        您的注释将字段“ 1”标记为已弃用,而不是字符串“ 2”。在对“ 3”的调用中,您传递字符串,而不是字段。因此,该方法不知道该值来自的字段,因此无法检查它的注释。 通过注释,您可以声明有关Java元素的信息,例如类,字段,变量,方法。您不能注释对象,例如字符串。 您链接到的文章讨论了注释形式参数。同样,被注释的是参数,而不是参数(传递的值)。如果将@Something放入方法参数,则此参数将始终与该方法的调用者传递的值无关地进行注释。 您可以执行以下操作-但是我不确定这是否是您想要的-
@Deprecated
private static final String OLD_PATH = \"old_path\";
private static final String NEW_PATH = \"new_path\";

public load(Node node){
    migrateProperty(node,getClass().getDeclaredField(\"OLD_PATH\"),getClass().getDeclaredField(\"NEW_PATH\") );
    // ...
}

//I want to validate that the String oldPath has the @Deprecated annotation
public void migrateProperty(Node node,Field<String> oldPath,Field<String> newPath) {
    if ( oldPath.getAnnotation(Deprecated.class) == null ) {
       // ... invalid
    }
    // ...
}
在这种情况下,您实际上传递的是字段,而不是值。     ,        已弃用\“ old \”(基于JavaDoc的Java 5之前的版本)的注释存储在已编译的类文件中,但不幸的是无法通过反射访问。 如果您可以选择使用\“ real \”注释(@ java.lang.Deprecated),则当然可以使用反射来获取类的所有声明字段,并检查它们是否为带@的静态字符串。不推荐使用的注释,并将其与传递的方法参数进行比较。 但是,这听起来很丑陋,我鼓励您找到另一种方法来检查不需要的参数。     ,        首先,您的\“ @ deprecated \”标记只是JavaDoc标记,而不是注释,因此它与编译器无关。 如果使用ѭ5批注,则会在不赞成使用的行的行中收到不赞成使用的警告:
@Deprecated
private static final String OLD_PATH = \"old_path\";
private static final String NEW_PATH = \"new_path\";
您也可以保留JavaDoc
@deprecated
标记,但是只有提供一些解释后,它才有用。当然,javadoc标记必须在ѭ8内。 但是,如果您想在运行时在
migrateProperty()
方法内检查所传递的字符串来自不赞成使用的变量,那是不可能的。通过方法调用得到的是对堆上String的引用。弃用仅是指该字段,也许只能在调用该方法之前进行检查。     ,        我不知道您的用例到底是什么,但是我不认为您可以使用@Deprecated来完成您想做的事情。当您将某项标记为不赞成使用时,您是在将字段,方法或类标记为NOT值。您可以在loadProperty中访问的就是值。 因此,以您的例子为例,我可以很容易地打电话给
new MyRepo().loadProperty(\"old_path\");
完全不参考OLD_PATH或NEW_PATH。解决方案很简单,您需要显式检查方法是否匹配。 (已添加isDeprecated方法)。您可以根据需要保留@Deprecated批注。
public class MyRepo {
    @Deprecated
    private static final String OLD_PATH = \"old_path\";
    private static final String NEW_PATH = \"new_path\";

    private boolean isDeprecated(String path) {
        return OLD_PATH.equals(\"old_path\");
    }

    //...

    public load(Node node){
        migrateProperty(node,OLD_PATH,NEW_PATH );

        //load the properties
        loadProperty(node,NEW_PATH);
    }

    //I want to validate that the String oldPath has the @Deprecated annotation
    public void migrateProperty(Node node,String oldPath,String newPath) {
        if (!isDeprecated(oldPath)) {
            throw new Exception(oldPath + \" is not deprecated\");
        }

        if(node.hasProperty(oldPath)){
            Property property = node.getProperty(oldPath);
            node.setProperty(newPath,(Value) property);
            property.remove();
        }
    }

    //I want to validate that the String path does not have the @Deprecated annotation
    public void loadProperty(Node node,String path) {
        if (isDeprecated(path)) {
            throw new Exception(path + \" is deprecated,please use \" + NEW_PATH);
        }

        //load the property from the node
    }
}
如果需要将此模式应用于多个类,那么您当然可以使其更加严格。     ,        \ .class \文件的检查是否符合您的“ compile”时间要求? FindBug允许对.class文件进行许多检查。您可以编写自定义插件来检查字段,方法和参数(以及许多其他内容)。这是一个旧教程 如果您设法编写一个代码,那么我将对使用该代码非常感兴趣:)     ,        我的方法是将其更改为编译器已经擅长的类型:类型检查。 基于示例中常量的使用,我将假设您具有一组已知的潜在值,这表明
enum
s。
public class MyRepo
    private enum Preferred {
        PATH(\"new_path\"),OTHER_THING(\"bar\");

        private String value;

        Preferred(String value) {
            this.value = value;
        }

        @Override
        public String toString() {
             return value;
        }
    }

    private enum Legacy {
        PATH(\"old_path\"),OTHER_THING(\"foo\");

        private String value;

        Legacy(String value) {
            this.value = value;
        }

        @Override
        public String toString() {
             return value;
        }
    }

    public load(Node node){
        migrateProperty(node,Legacy.PATH,Preferred.PATH);

        //load the properties
        loadProperty(node,Preferred.PATH);
    }

    public void migrateProperty(Node node,Legacy oldBusted,Preferred newHotness) {
        if (node.hasProperty(oldBusted)) {
            Property property = node.getProperty(oldBusted);
            node.setProperty(newHotness,(Value) property);
            property.remove();
        }
    }

    public void loadProperty(Node node,Preferred path) {
        //load the property from the node
    }
}
如果这不符合您的需求,请添加有关使用情况以及您要解决的根本问题的更多信息。 如果您真的想通过注释来完成此任务,那么看来有一种方法。 Java 6在ѭ14中内置了批注处理API,它们似乎实际上是编译器的插件。他们可以做您想要做的事情,还有很多其他事情,但至少在乍一看时,它们似乎很深奥。这看起来像一个不错的介绍:http://today.java.net/pub/a/today/2008/04/10/source-code-analysis-using-java-6-compiler-apis.html     ,根本不可能在编译时执行此操作。 首先,@Depreciated批注可以引用String字段,但是无论如何都没有附加字符串值。 其次,即使您可以以某种方式标记带有注释的字符串值,Java类型系统中的任何内容都不能让您声明只能传递带有特定注释的值-注释信息甚至在编译时也不一定可用。 由于第1点,注释处理不起作用。由于第2点,所有其他方案仅在运行时起作用。 要实现编译时检查,最自然的做法是创建一个包含字符串的所有有效值的枚举。     

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-