Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 仅限公共访问的注释_Java_Reflection_Annotations - Fatal编程技术网

Java 仅限公共访问的注释

Java 仅限公共访问的注释,java,reflection,annotations,Java,Reflection,Annotations,我想强制执行此注释只能放置在公共成员(字段或方法)上。这可能吗?我对这个话题的简短研究表明没有 @Target({ElementType.FIELD,ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface CsvAttribute { String columnName(); int position(); } 我的目标是不使用try-catch块来实现这一点。既然我可以访问对象,

我想强制执行此注释只能放置在公共成员(字段或方法)上。这可能吗?我对这个话题的简短研究表明没有

@Target({ElementType.FIELD,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface CsvAttribute {
     String columnName();
     int position();
}
我的目标是不使用try-catch块来实现这一点。既然我可以访问对象,我可以不经反射地执行此操作吗

public abstract class CsvExportable {

protected final Map<Integer, String> convertFieldsToMap(){
    final Method[] m = this.getClass().getDeclaredMethods();
    return new ArrayList<>(Arrays.asList(m)).stream()
            .filter(p -> p.isAnnotationPresent(CsvAttribute.class))
            .collect(Collectors.toMap(
                    p -> p.getAnnotation(CsvAttribute.class).position(),
                    p -> this.invokeGetter(p)));
}

private String invokeGetter(Method m){
    try {
        return Objects.toString(m.invoke(this), "");
    } catch (IllegalAccessException | InvocationTargetException e) {
        LOG.error("@CsvAttribute annotation must be placed on public getters!");
        e.printStackTrace();
    }
    return "";
}

}
公共抽象类CsvExportable{
受保护的最终地图转换程序{
final方法[]m=this.getClass().getDeclaredMethods();
返回新的ArrayList(Arrays.asList(m)).stream()
.filter(p->p.isAnnotationPresent(csvatAttribute.class))
.collect(collector.toMap)(
p->p.getAnnotation(csvatAttribute.class).position(),
p->this.invokeGetter(p));
}
私有字符串调用器(方法m){
试一试{
返回Objects.toString(m.invoke(this),“”);
}捕获(IllegalAccessException | InvocationTargetException e){
LOG.error(“@csvatAttribute注释必须放在公共getter上!”);
e、 printStackTrace();
}
返回“”;
}
}

不据我所知,如果不考虑到需要进行注释处理,您无法在不进行反射的情况下执行此操作。您可以使用修饰符#isPublic来确定字段或方法是否是公共的。如果要支持所指示的方法,还应使用ElementType.METHOD

另一方面,请随意查看或查看一些反射API,它们可能会让您的生活更轻松

//如果是方法或字段
如果(!Modifier.isPublic(方法)){
抛出新的IllegalStateException(“修饰符必须是公共的”);
}
//如果一个字段
如果(!Modifier.isPublic(字段)){
抛出新的IllegalStateException(“修饰符必须是公共的”);
}
@Target({ElementType.FIELD,ElementType.METHOD})

不据我所知,如果不考虑到需要进行注释处理,您无法在不进行反射的情况下执行此操作。您可以使用修饰符#isPublic来确定字段或方法是否是公共的。如果要支持所指示的方法,还应使用ElementType.METHOD

另一方面,请随意查看或查看一些反射API,它们可能会让您的生活更轻松

//如果是方法或字段
如果(!Modifier.isPublic(方法)){
抛出新的IllegalStateException(“修饰符必须是公共的”);
}
//如果一个字段
如果(!Modifier.isPublic(字段)){
抛出新的IllegalStateException(“修饰符必须是公共的”);
}
@Target({ElementType.FIELD,ElementType.METHOD})

不可能在注释本身中进行配置,但如果有编译时注释处理器,可以在编译时注释处理器中进行配置。如果带注释的元素无效,只需抛出异常即可


如果您只是在运行时处理注释,那将没有多大帮助。您可以触发运行时异常,但不会出现编译错误。

无法在注释本身中配置该异常,但如果有编译时注释处理器,您可以在编译时注释处理器中进行配置。如果带注释的元素无效,只需抛出异常即可


如果您只是在运行时处理注释,那将没有多大帮助。您可以触发运行时异常,但不会出现编译错误。

即使强制注释仅出现在
public
成员中,编译器也不知道
方法始终表示
public
方法。因此,它将继续坚持捕获
IllegalAccessException
。此外,无论该方法是否为
public
,它都可能抛出异常,因此,您始终必须处理
InvocationTargetException
。换句话说,无论如何都无法绕过try-catch块。顺便问一下,
StringUtils.EMPTY
的意义是什么,尤其是当您也在同一方法中使用直截了当的
”时?命名常量在名称告诉您一些事情时很有用,但在名称告诉您的内容不超过常量本身时就不有用了。每个人都可以看到,
是一个空字符串,因此仅用单词
empty
说同样的话并不能证明向第三方库添加依赖项是合理的。另一个故事是
“@csvatribute注释必须放在public getter上!”
常量,它甚至包含一个隐式假设,即该方法是用
@csvatribute
注释的,它不在
invokeGetter
方法的范围内,但这仍然是调用方的责任,因此日志消息将是在类范围内声明的常量的自然候选。无论如何,考虑到你的实际问题,我想知道你是否认为相反;当您使用
java.lang.invoke
API时,您可以放弃方法必须是
public
的要求。顺便说一句,
新建ArrayList(Arrays.asList(m)).stream()
做了两次不必要的迂回:不需要复制通过
Arrays.asList(m)创建的
List
进入
数组列表
,就像
数组一样。asList(m).stream()
也可以,但是你甚至可以在没有任何
列表的情况下创建
:只要
数组。stream(m)
。这就是我在第一条评论中说的,即使你强制该方法公开,try-catch块将保留。但我不是说使用
setAccessible(true)
,而是说使用
java.lang.invoke
API,它允许调用方将必要的访问权限转移到实用工具方法,这样它就不会因为访问权限不足而失败。还可以选择为访问器方法生成
Function
对象,每个类只需执行一次,因此后续使用不再需要try-catch块。不过,初始化将更加复杂