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