自定义Java类的动态构造函数结构

时间:2016-02-18 18:00:38

标签: java annotations

我想创建一个包含大约60个double类型字段的类。然后我需要创建这个类的不同实例,只通过构造函数来评估其中一些字段(大约4-5个字段),将其他字段保留为默认值(0)。

问题在于我不想拥有60个参数构造函数,因为填充所有必需字段会浪费时间。此外,我不想创建公共方法来逐个设置字段值。

我正在考虑java Annotation,像

那样
StatusListener statusListener = new StatusListener() {
    @Override
    public void onStatus(Status status) {
        //your code to manage the statuses
    }
    //other requiredly-overriden methods
}
ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
configurationBuilder.setOAuthConsumerKey("XXXXX");
configurationBuilder.setOAuthConsumerSecret("XXXXXXX");
TwitterStream twitterStream = new TwitterStreamFactory(configurationBuilder.build()).getInstance(new AccessToken("XXXXX", "XXXXXXX"));
twitterStream.addListener(statusListener);

//from here is different at your code

//you need to set up your user list, with their users id's!
long[] userslist = YOUR USER LIST;
//then you create a filter
FilterQuery filtre = new FilterQuery();
//and use that filter to follow the users that you want and to start the stream
filtre.follow(userslist);
twitterStream.filter(filtre);

这样我就可以只指定我需要的参数

public @interface MyAnnotation{

    public double f1() default 0;
    public double f2() default 0;
    public double f3() default 0;
    ...
    public double f60() default 0;

}

无论如何,我没有太多的经验,我不确定它能否应付我的需求。从广义上讲,我的目标是:

@MyAnnotation(f1=2.1 , f48=3.5)

有没有一种方法可以使用类构造函数来获得类似的东西?

P.S。我不是程序员,但我非常了解Java反射,所以如果需要它们就没问题。

6 个答案:

答案 0 :(得分:1)

这样的东西?或者我离开了?

    public class Blank{
      public void Blank(int [] fSpots, double[] vaules0{
            }

然后循环设置特定点等于值?

答案 1 :(得分:1)

查看“构建器”解决方案。您创建了一个镜像主类的可变类,每个字段都有setter(可能使用流畅的api以便于访问),然后让主不可变类将构建器作为参数并从中复制数据。 为避免手动创建庞大的构建器,您可以使用一些帮助程序,例如 https://projectlombok.org/features/Builder.html

或者,您可以使用groovy http://docs.groovy-lang.org/latest/html/documentation/#_named_argument_constructor 斯卡拉 http://docs.scala-lang.org/tutorials/tour/named-parameters.html 或者使用其中一个活动注释进行xtend。

答案 2 :(得分:0)

一种方法是实现不同的构造函数,每个构造函数只包含应填充的一些字段。如果您只想使用一些合理的值组合,这是一种有价值的方法。

此外,可以使用存储值的Map,将所有未存储的值解释为零。这个映射可以作为参数提供给构造函数。

一般来说,如果遇到如此庞大的数据类,就应该考虑设计。也许它应该被分成几个类用于不同的目的,也许不同的数据结构,如数组,映射或集合是合适的。

答案 3 :(得分:0)

我相信fluent interface可以帮到你。请记住,Java中double的默认值已经是0.0。

public class MyClass {

double f1;
double f2;

public MyClass() {
}

public MyClass f1(double f1) {
    this.f1 = f1;
    return this;
}

public MyClass f2(double f2) {
    this.f2 = f2;
    return this;
}

}



public class Test {

MyClass myClass1 = (new MyClass()).f1(1);
MyClass myClass2 = (new MyClass()).f2(2);
MyClass myClass3 = (new MyClass()).f1(1).f2(2);

}

答案 4 :(得分:0)

这很疯狂,但是:

enum Field {

  F1, F2, F3, F48;

  Arg set(Double value)
  {
    return new Arg(this, value);
  }

  static final class Arg
  {
    final Field field;

    final Double value;

    private Arg(Field f, Double v)
    {
      this.field = f;
      this.value = v;
    }
  }

}

final class BadModel
{

  private static final Double ZERO = (double) 0;

  private final Map<Field, Double> fields = new EnumMap<>(Field.class);

  BadModel(Field.Arg... args)
  {
    for (Field.Arg e : args)
      this.fields.put(e.field, e.value);
  }

  Double get(Field field)
  {
    return fields.getOrDefault(field, ZERO);
  }

  public static void main(String... argv)
  {
    BadModel obj = new BadModel(Field.F1.set(2.1), Field.F48.set(Math.PI));
    double f3 = obj.get(Field.F3);
    System.out.println(f3);
  }

}

我鼓励你退后一步,在假设有稀疏字段的对象是答案之前,先解决你的根本问题。

答案 5 :(得分:0)

我还没找到我想要的东西。无论如何,我发布了我选择的解决方案以防万一有人感兴趣。

我在内部创建了一个Class Fields

public class MyClass{
    double f1;
    double f2;
    ...
    double fn;
}

然后我创建了一个Enum嵌入getFieldName()方法,该方法返回String等于MyClass field名称:

public enum MyEnum{
    F1("f1"),
    F2("f2"),
    ...
    FN("fn");

    private String name;

    private MyEnum(String fieldName){
        name = fieldName;
    }

    public String getFieldName(){
        return name;
    }
}

然后我为MyClass创建了一个构造函数,利用java reflections,将值设置为指定的字段。

public class MyClass{
    double f1;
    double f2;
    ...
    double fn;

    public MyClass(MyEnum[] fieldsName, double[] values){
        for(int i=0; i<fieldsName.lenght; i++){
            try{
                Field f = this.getClass().getDeclaredField(fieldsName[i].getFieldName());
                f.set(this,values[i])
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }
}