Eclipse认为什么是“简单的getter”或“简单的setter”?

时间:2013-08-22 23:39:43

标签: java eclipse debugging

我经常使用Eclipse调试器,这总是让我对IDE有所了解。步骤过滤是一个非常宝贵的工具,这样我就不会进入没有源代码的类或者我根本就不感兴趣的类。但是Eclipse并没有在大多数情况下使用它。特别是,有“过滤简单的getter”和“过滤简单的setter”的选项。

我可能会使用一个只返回成员变量值的getter。

private String value;
public String getValue()
{
    return value;
}

或许是懒惰地实例化昂贵物品的吸气剂。

private IObjectFactory instance;
public IObjectFactory getInstance()
{
    if (instance == null)
        instance = ObjectFactory.createFactory();
    return instance;
}

我可能会使用只设置成员变量值的setter。

private String value;
public void setValue(String value)
{
    this.value = value;
}

我可能想支持流利的语法。

private String value;
public ObjectFactory setValue(String value)
{
    this.value = value;
    return this;
}

或者也许做一些验证或事件触发。

private String user;
public void setUser(String user)
{
    if (StringUtils.isBlank(user))
        throw ExceptionHelper.argumentNull("user");
    this.user = user;
}

private String title;
public void setTitle(String title)
{
    if (!StringUtils.equals(this.title, title))
    {
        this.title= title;
        onPropertyChanged("title", title);
    }
}

对于这些用途中的每一个,使用eclipse步骤进入这些方法的代码......

Eclipse认为“简单的getter”或“简单的setter”是什么?

过滤器肯定已启用:

step filtering settings

如果重要,我正在使用Eclipse Kepler build 20130614-0229。我正在使用JRE6来运行Eclipse和托管Java 1.4 Web应用程序的Tomcat 7服务器。虽然我们最终以1.4为目标,但它是使用JDK6在本地编译的,所以我不认为这是一个问题。我确实安装了JRebel并且正在使用,也许类加载器干扰了确定什么被认为是“简单”的算法?结合启用“逐步过滤器”选项,它可能会逐步执行我的代码。在考虑这个之后我会进一步尝试。

2 个答案:

答案 0 :(得分:2)

好的,我认为我追踪了它。

在正常情况下,如果启用了这些过滤器,则会跳过普通的getter和plain setter(问题中的示例1和3)。如果安装并使用了一个特殊的类加载器(如JRebel)来修改挂钩到它们的方法,它似乎会干扰Eclipse的算法,这些算法确定方法是“简单的getter”还是“简单的setter”。

所以在代码中可能看起来像这样的getter:

public String getValue()
{
    return this.value;
}

可能会从JVM的角度改变看起来像这样:

public String getValue()
{
    Proxy proxy = getProxy(this);
    return (String)proxy.invoke("getValue", new Object[] { });
    // this is all just an example,
    // it's defintely way more complicated than this
}

这个改变的代码让Eclipse感到困惑,认为“这不是一个简单的getter,所以步入它”。它确实如此,但实际的源代码是我真正的简单getter,然后让我感到困惑的是“为什么Eclipse会进入这个简单的getter?”

我进行了一项非常人为的测试,试图让步骤过滤工作。

import org.apache.commons.lang.StringUtils;

public class Program
{
    public static void main(String[] args)
    {
        User bob = new User("0001", "Bob");
        String id = bob.getId(); //stepped over
        String name = bob.getName(); //stepped over
        IHome home = bob.getHome(); //stepped into

        bob.setId("foo"); //stepped into
        bob.setName("Bobby"); //stepped over
        String asString = bob.setNameFluent("Bobbo").toString(); //stepped into
        IHome newHome = Neighborhood.getHome("moo");
        bob.setHome(newHome); //stepped into
        return;
    }

    static class User
    {
        private String id;
        private String name;
        private IHome home;

        public User() { this("0001", null); }
        public User(String id, String name) { this.id = id; this.name = name; }

        public String getId() // simple
        {
            return id;
        }
        public String getName() // simple
        {
            return name;
        }
        public IHome getHome() // not simple
        {
            if (home == null)
                home = Neighborhood.getHome(id);
            return home;
        }

        public void setId(String id) // not simple
        {
            if (StringUtils.isBlank(id))
                throw ExceptionHelper.argumentBlank("id");
            this.id = id;
        }
        public void setName(String name) // simple
        {
            this.name = name;
        }
        public User setNameFluent(String name) // not simple
        {
            this.name = name;
            return this;
        }
        public void setHome(IHome home) // not simple
        {
            if (home != null)
            {
                this.home = home;
                onHomeChanged();
            }
        }

        protected void onHomeChanged()
        {
            this.id = home.getId();
        }
        public String toString()
        {
            return "User { name=" + getName() + ", home=" + getHome() + " }";
        }
    }

    static interface IHome
    {
        String getId();
        String getLocation();
    }

    static class Neighborhood
    {
        public static IHome getHome(String id)
        {
            return new Home(id);
        }

        static class Home implements IHome
        {
            private String id;
            public Home(String id) { this.id = id; }
            public String getId() { return id; }
            public String getLocation() { return "Home" + id; }
            public String toString() { return "Home: " + getLocation(); }
        }
    }

    static class ExceptionHelper
    {
        public static IllegalArgumentException argumentBlank(String name)
        {
            return new IllegalArgumentException("Argument " + name + " must not be blank");
        }
    }
}

使用默认配置(没有JRebel的JDK6),步骤过滤似乎有效。试图进入简单的方法实际上跨过它们。在启用JRebel并再次单步执行代码之后,它进入了所有方法。如果启用“逐步过滤”,则无关紧要。

<强> tldr;

通过使用JRebel,它使Eclipse混淆的魔力使得简单的getter和简单的setter看起来比原来更复杂。禁用JRebel将使过滤器按预期工作。

答案 1 :(得分:1)

Here是Eclipse网站上的一个页面,它更详细地介绍了两个选项

过滤简单的getter:

  

此选项控制在步进时是否应始终过滤简单的Java bean样式的getter

过滤简单的setter:

  

此选项控制在步进时是否应始终过滤简单的Java bean样式的setter

从它的声音中,你给的例子1和3看起来就像他们在这里所说的那样。不知道为什么你会看到你的行为。

编辑:看起来原始海报发现了这个问题;关于JRebel过分复杂方法的事情。