Agile Javaв„ў: Crafting Code with Test-Driven Development
this
Look at the Student class code to see if it can be improved. class Student { String myName; Student(String name) { myName = name; } String getName() { return myName; } }
The code appears clean, but naming the field myName is oh so academic. Show your professionalism by using a better name. A first thought might be to call the field studentName. However, that introduces duplication in the form of name redundancyit's clear that the field represents a student's name, since it is defined in the class Student. Also, you generally name your get methods after the fields, so the redundancy would become very apparent when you coded a statement like: student.getStudentName();
How about simply name? The problem with using name as the field name is that it clashes with the formal parameter name of the Student constructorboth would be called name. try it, though, and see what happens. class Student { String name; Student(String name) { name = name; } String getName() { return name; } } This should pass compilation (you might see a warning). Run your test, however, and it will fail: junit.framework.ComparisonFailure: expected:<Jane Doe> but was:<null>
Why? Well, part of the problem is that the Java compiler allows you to name fields the same as formal parameters, or even the same as local variables. When the code is compiled, Java tries to figure out which name you meant. The resolution the compiler makes is to use the most locally defined name, which happens to be the name of the formal parameter. The statement name = name;
thus just results in the object stored in the parameter being assigned to itself. This means that nothing is getting assigned to the instance variable (field) called name. Field references that are not assigned an object have a special value of null, hence the JUnit message: expected:<Jane Doe> but was:<null>
There are two ways to ensure that the value of the formal parameter is assigned to the field: Either ensure both variables have different names or use the Java keyword this to differentiate them. Using this is the most common approach. The first approach means you must rename either the parameter or the field. Java programmers use many differing conventions to solve this naming issue. One is to rename the formal parameter so that it uses a single letter or is prefixed with an article. For example, name could be renamed to n or aName. Another common choice is to rename the field by prefixing it with an underscore: _name. This makes use of the field stand out like a sore thumb, something that can be very valuable when trying to understand code. There are other schemes, such as prefixing the argument name with the article a or an (aName). The second approach for disambiguating the two is to use the same name for both, but where necessary refer to the field by prefixing it with the Java keyword this. class Student { String name; Student(String name) { this.name = name; } String getName() { return name; } }
The this keyword represents a reference to the current objectthe object for which the code is currently executing. The statement in the above example assigns the value of the formal parameter name to the field name. Make sure your test now passes after making this change. From now on, remember to recompile after you change the code and before running your teststhere will be few reminders in the rest of the book. |