Дата публикации: 03.11.2013 22:49:32
I would like to discuss code conventions. In particular, the usage of the this keyword.
Recently we have argued with one of my colleagues again. I always use the this.name pattern to access class fields. Whereas he says that I should not differ from everybody else and use this to avoid shadowing only. Let me explain my position on the question.
The this keyword is commonly used to access the class fields, which are shadowed by a method or constructor parameter. For example,
public class Bean { private int value; public void setValue(int value) { this.value = value; } public int getValue() { return this.value; } }
In the setter, you need to use the this keyword because of the shadowing unless you are going to look for synonyms to name parameters. In the getter, the this keyword can be omitted, but I never do so due to the following reasons.
First, one of the reasons for the creation of the Code Conventions for the Java Programming Language document was an improvement of code readability. I think that the this.name identifier bears more clarity than just name does. If you follow such pattern, a code maintainer will quickly detect whether it is a class field or a local variable used.
Second, I do not like conditional rules, when the way you implement a standard action depends on some other conditions. Instead, I would rather prefer consistency. If class fields are accessed by using the this keyword in one case, it is reasonable to access class fields by using the same pattern in the rest of the situations.
Third, the this keyword allows developers to avoid hard-to-detect errors when they modify a method with a huge code and introduce a variable that shadows a class field. For example, let's declare the component variable in the following method that is huge. The rest of the method will use this local variable instead of using a class field. As a result, the code works differently. There are no compiler-time errors, but the method results are unexpected at run-time.
protected void addImpl(Component comp, Object constraints, int index) { synchronized (getTreeLock()) { /* Check for correct arguments: index in bounds, * comp cannot be one of this container's parents, * and comp cannot be a window. * comp and container must be on the same GraphicsDevice. * if comp is container, all sub-components must be on * same GraphicsDevice. */ GraphicsConfiguration thisGC = this.getGraphicsConfiguration(); if (index > component.size() || (index < 0 && index != -1)) { throw new IllegalArgumentException("illegal component position"); } checkAddToSelf(comp); checkNotAWindow(comp); if (thisGC != null) { comp.checkGD(thisGC.getDevice().getIDstring()); } /* Reparent the component and tidy up the tree's state. */ if (comp.parent != null) { comp.parent.remove(comp); if (index > component.size()) { throw new IllegalArgumentException("illegal component position"); } } //index == -1 means add to the end. if (index == -1) { component.add(comp); } else { component.add(index, comp); } comp.parent = this; adjustListeningChildren(AWTEvent.HIERARCHY_EVENT_MASK, comp.numListening(AWTEvent.HIERARCHY_EVENT_MASK)); adjustListeningChildren(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK, comp.numListening(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK)); adjustDescendants(comp.countHierarchyMembers()); invalidateIfValid(); if (peer != null) { comp.addNotify(); } /* Notify the layout manager of the added component. */ if (layoutMgr != null) { if (layoutMgr instanceof LayoutManager2) { ((LayoutManager2)layoutMgr).addLayoutComponent(comp, constraints); } else if (constraints instanceof String) { layoutMgr.addLayoutComponent((String)constraints, comp); } } if (containerListener != null || (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0 || Toolkit.enabledOnToolkit(AWTEvent.CONTAINER_EVENT_MASK)) { ContainerEvent e = new ContainerEvent(this, ContainerEvent.COMPONENT_ADDED, comp); dispatchEvent(e); } comp.createHierarchyEvents(HierarchyEvent.HIERARCHY_CHANGED, comp, this, HierarchyEvent.PARENT_CHANGED, Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK)); if (peer != null && layoutMgr == null && isVisible()) { updateCursorImmediately(); } } }
PS. This article was originally posted on the Java.net site.