Java 爪哇:有没有可能;模拟;通过自定义注释实现默认参数值(如C+;+;,Python)的功能? < >我发现C++中缺省参数值的特性非常有用。

Java 爪哇:有没有可能;模拟;通过自定义注释实现默认参数值(如C+;+;,Python)的功能? < >我发现C++中缺省参数值的特性非常有用。,java,eclipse,annotations,default-parameters,Java,Eclipse,Annotations,Default Parameters,目前,java没有以本机方式提供此功能 当人们需要它时,他们只是用相同的名字定义了很多函数 这是一个非常肮脏的实现 所以我想知道有没有更优雅的方法 例如,我可以使用注释来实现这一点吗 有什么想法吗?我可以看到两种方法:可变参数和注释 以下是Java世界中常见的一种方法: public void foo() { foo(null); } public void foo(String bar) { if (bar==null) { // Set bar to a d

目前,java没有以本机方式提供此功能

当人们需要它时,他们只是用相同的名字定义了很多函数

这是一个非常肮脏的实现

所以我想知道有没有更优雅的方法

例如,我可以使用注释来实现这一点吗

有什么想法吗?

我可以看到两种方法:可变参数和注释

以下是Java世界中常见的一种方法:

public void foo() {
    foo(null);
}

public void foo(String bar) {
    if (bar==null) {
        // Set bar to a default value 
        bar = ...; 
    }
}
以下是解决办法:

解决方法1:可变参数(Java 5+) 解决方案2:注释(Java 5+) 如果使用注释实现默认参数,则需要某种框架来处理注释并为您调用方法。框架将负责在调用方法之前初始化参数

例如,当使用JAX-RS实现构建API REST时,您可以依赖这种机制

// ...
public Response foo(@DefaultValue("default") String bar) {
    return ...;
}

不,java没有与
C++
等价的默认值

C++
中,您可以编写如下函数

int add(int a, int b = 3)
在Java中,可以使用过编码

public int add(int a){
    add(a, 3);
}

public int add(int a, int b){
    ....
}
从客户端的角度来看,它等于
c++
中的默认值。例如

calc.add(1);
calc.add(1, 2);

为此,要使用注释,需要在方法上使用包装器,该包装器根据注释和传入参数读取和修改参数


如果对这些方法的访问由上下文控制(例如:Springbeans中的方法),那么实现起来就相当容易了。您可能想考虑代理引入的延迟,并确保所有调用都是通过代理完成的(没有本地调用)。以下是一个例子:

首先定义注释:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD) 
public @interface DefaultValue {
    String defaultValue() default "";
}
@Target
指定了
注释的类型,可能的目标是:

ElementType.ANNOTATION_TYPE
ElementType.CONSTRUCTOR
ElementType.FIELD
ElementType.LOCAL_VARIABLE
ElementType.METHOD
ElementType.PACKAGE
ElementType.PARAMETER
ElementType.TYPE
例如,现在您有了一个
UserName
对象,它是在创建新用户时创建的

public class UserName {

    @DefaultValue(defaultValue = "<empty>")
    private String name;

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return this.name;
    }

    public String toString() {
        return "Username is: " + this.name;
    }
}
这是一个简单的例子,但我希望它能帮助你

注:

如果不希望为每个字段指定默认值,也可以简单地对字段进行注释,如下所示:

@DefaultValue
private String name;

并且将使用
DefaultValue
类中定义的默认值(在我的示例中,它将默认为空字符串
“”

我不认为它不美观,因为您明确指定参数
b
是可选的。我认为如果以后考虑重构或引入默认值,
C++
aproach更容易出错。当有大量可选参数时,这就变得不雅观了。这是一些人喜欢BueDeLoad模式的原因之一,例如,即使这种方式被认为是更好的,也会在C++中出现重载。对于构造函数,我更喜欢它的委托构造函数语法,而不是“在第一行中必须调用
this()
super()
”方法。是否有一些通用Java应用程序@DefaultValue实现的现成代码我不知道这样的实现。但是,您可以检查以下答案:。特别是选项#4:可选类。我将仅将注释限制为方法参数。您是正确的,更新了答案以适应不同的注释类型:)可能重复的
public class CreateName {
    public static void main (String [] args) throws NoSuchFieldException, SecurityException {
        System.out.println(checkUserName(new UserName()));
    }

    public static UserName checkUserName(UserName user) throws NoSuchFieldException, SecurityException {
        if (user.getName() == null) {
            Field userNameField = UserName.class.getDeclaredField("name");

            if (userNameField.isAnnotationPresent(DefaultValue.class)) {
                Annotation ann = userNameField.getAnnotation(DefaultValue.class);
                DefaultValue value = (DefaultValue) ann;
                user.setName(value.defaultValue());
            }
        }
        return user;
    }
}
@DefaultValue
private String name;