简体   繁体   English

自动为变量生成某些方法

[英]Generating certain methods for variables automatically

I have a question of how, if possible, one can generate methods automatically by only providing variable of a spefic kind. 我有一个问题,如果可能的话,如何通过仅提供特定类型的变量来自动生成方法。

Let's illustrate my question with simple example: Assuming I have multiple variables linked to LinkedLists and I would like to give each certain methods; 让我们用简单的例子说明我的问题:假设我有多个链接到LinkedLists的变量,我想给出每个特定的方法; for example setters and getters methods: 例如setter和getters方法:

private LinkedList football = new LinkedList();
private LinkedList jogging = new LinkedList();

public LinkedList getFootball() {
    return football;
}
public void setFootball(LinkedList football) {
    this.football = football;
}
public LinkedList getJogging() {
    return jogging;
}
public void setJogging(LinkedList jogging) {
    this.jogging = jogging;
}

If number of variables gets long (example only contains 2), this will produce very long and rather repetetive peace of code, illustrated above. 如果变量的数量变长(例子只包含2),这将产生非常长且相当重复的代码和平,如上所示。

Is there any way, if this is indeed a possability, to generalize the above pattern so I can create both methods by just creating an instance of LinkedList? 有没有办法,如果这确实是一个可能性,概括上面的模式,所以我可以通过创建LinkedList的实例创建两个方法?

PS: using foreach loop and generalizing it for arbitrary element does NOT WORK. PS:使用foreach循环并将其概括为任意元素不起作用。

You might be looking for Lombok : 您可能正在寻找龙目岛

You can annotate any field with @Getter and/or @Setter, to let lombok generate the default getter/setter automatically. 您可以使用@Getter和/或@Setter注释任何字段,让lombok自动生成默认的getter / setter。

A default getter simply returns the field, and is named getFoo if the field is called foo (or isFoo if the field's type is boolean). 默认的getter只返回字段,如果字段名为foo,则命名为getFoo(如果字段的类型为boolean,则命名为isFoo)。

In your case, this class 在你的情况下,这个类

@Getter
@Setter
public class MyClass {
    private LinkedList football = new LinkedList();
    private LinkedList jogging = new LinkedList();
}

would lead to the following code: 会导致以下代码:

public class MyClass {
    private LinkedList football = new LinkedList();
    private LinkedList jogging = new LinkedList();

    public LinkedList getFootball() {
        return football;
    }

    public void setFootball(LinkedList football) {
        this.football = football;
    }

    public LinkedList getJogging() {
        return jogging;
    }

    public void setJogging(LinkedList jogging) {
        this.jogging = jogging;
    }
}

However, Lombok requires some compiler configuration , so while you're at it, you might as well consider to check out Kotlin , where your class can be written simply as this: 但是,Lombok 需要一些编译器配置 ,所以当你在它的时候,你也可以考虑查看Kotlin ,你的类可以简单地写成:

class MyClass {
    var football = LinkedList<Any?>()
    var jogging = LinkedList<Any?>()
}

You can't do that at run-time. 你不能在运行时这样做。 However, a lot of IDE:s have an option to autogenerate getters and setters. 但是,很多IDE都可以选择自动生成getter和setter。

For instance in Eclipse, you open the context menu with a left click and look under "Source", or press Alt + Shift + s to open the source menu. 例如,在Eclipse中,左键单击打开上下文菜单,在“Source”下查看,或按Alt + Shift + s打开源菜单。 There you'll find an option labeled "Generate Getters and Setters", that will open a dialog button that lets you choose what setters and getters to create, where to insert them in the code etc.. 在那里你会找到一个标记为“Generate Getters and Setters”的选项,它会打开一个对话框按钮,让你选择要创建的setter和getter,在代码中将它们插入的位置等等。

You are asking for various sorts of trouble with code readability, optimizations and loss of encapsulation, not to mention losing compile-time checks for correct variable names. 您要求在代码可读性,优化和封装丢失方面遇到各种麻烦 ,更不用说丢失正确变量名称的编译时检查。 Regardless, you can create a generic setter and getter (in this case for LinkedLists) through reflection like this: 无论如何,您可以通过这样的反射创建一个通用的setter和getter(在本例中为LinkedLists):

 public void setter(String name, LinkedList value) throws IllegalArgumentException {
    try {
      Field field = getClass().getDeclaredField(name);
      field.setAccessible(true);
      field.set(this, value);
      field.setAccessible(false);
    } catch (NoSuchFieldException | IllegalAccessException e) {}
  }

  public LinkedList getter(String name) {
    LinkedList ret = null;
    try {
      Field field = getClass().getDeclaredField(name);
      field.setAccessible(true);
      Object object = field.get(this);
      if (object instanceof LinkedList) {
        ret = (LinkedList) object;
      }
      field.setAccessible(false);
    } catch (NoSuchFieldException | IllegalAccessException e) {
      e.printStackTrace();
    }
    return ret;
  }

Why not use a map to organize your lists? 为什么不使用地图来整理列表? I made up a runnable example for you: 我为你编写了一个可运行的例子:

import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;

public class ListsManager {

    Map<String, LinkedList<String>> lists;

    public static void main(String[] args) {
        ListsManager lm = new ListsManager();
        System.out.println(lm.getList("football"));
    }

    public ListsManager(){
        //initialize map
        lists = new HashMap<String, LinkedList<String>>();
        //add lists
        lists.put("football", new LinkedList<String>());
        lists.put("jogging", new LinkedList<String>());
        //fill lists with objects
        lists.get("football").add("football 1");
        lists.get("football").add("football 2");
        lists.get("jogging").add("jogging 1");
        lists.get("jogging").add("jogging 2");
    }

    public void setList(String id, LinkedList list){
        lists.put(id, list);
    }

    public LinkedList getList(String id){
        return lists.get(id);
    }

}

This way you can address the lists via an ID. 这样您就可以通过ID来处理列表。 The example prints [football 1, football 2] 打印[football 1, football 2]

EDIT: I used lists of strings - of course you can change the generics to whatever you want. 编辑:我使用了字符串列表 - 当然,您可以将泛型更改为您想要的任何内容。

If you need something like this, I'd suggest you use the Apache DynaBean . 如果你需要这样的东西,我建议你使用Apache DynaBean It is essentially a Wrapper around a Map. 它本质上是围绕地图的包装器。 But this is only really sensible if you don't know the properties of your bean at compile time. 但是,如果您在编译时不知道bean的属性,那么这才是真正明智的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM