Author Archive

Listeners and Adapters

Thursday, September 3rd, 2009

Occasionally implementing a Listener leads to an explosion of ugly empty boiler-plate methods. In such cases it is usually better to extend a matching adapter class and only override the needed methods.

The next IntelliJ IDEA Maia EAP build will make switching between implementing a Listener or extending an Adapter easier — with newly added Listener implementation could be replaced with Adapter extension inspection (also announced on Twitter).

This new inspection quickly highlights any implementations of Listeners which contain empty methods and offers to replace them with an extension of the relevant Adapter class.

A quick Alt+Enter, Enter replaces the verbose listener code by a more compact use of an Adapter. If you ever need to return to an implementation of a Listener, there is a new complementary intention to make this journey back quick and painless — Replace Adapter Extension with Listener implementation.

Avoiding Assert Statements with Constant Conditions

Thursday, April 2nd, 2009

Though assert statements are very useful when it comes to checking runtime assumptions, using them to verify conditions that are constant is not so wise. Assert conditions that always evaluate to true are particularly unnecessary because they will never throw an error and can only serve to use up the CPU resources.
Here is an example from com.sun.java.swing.plaf.gtk.GTKDefaultEngine:

Assert condition true is a constant

IntelliJ IDEA 9 will bring you the assert statement condition is constant inspection, which will detect such assert statements, except for boolean literal false, because it is often used in code which is known or supposed to be unreachable.

Towards Side Effectless Assert Statements

Friday, March 27th, 2009

It is a well known rule that assert statements should cause no changes in state outside of them (aka side effects). Until now, you could only check if this rule was followed by visually inspecting the code. In IntelliJ IDEA 9 a new assert statement with side effects inspection will be available to help you keep assert statements free of side effects.

'assert' has side effects warning

The inspection will warn about modification of variables and fields inside of the assert statement. The assert statement will also be reported if a method called by it modifies any fields.

IntelliJ IDEA 7 Milestone 1: Better Code Inspections, Intention Actions and more

Wednesday, April 18th, 2007

Like any new release, IntelliJ IDEA 7 Milestone 1 contains many new features. So many in fact, it is probably impossible to notice them all. Among the many hundreds of inspections and intentions already present in the product, a new inspection or intention may be difficult to notice. Each by itself is just a small feature, but together they are quite powerful.


Here I will list all new Java inspections and intentions I personally have implemented for IntelliJ IDEA 7 Milestone 1. Note that this is not a complete list of all new inspections and intentions in the Milestone, just the ones which are new to the InspectionGadgets and IntentionPowerPack plugins. Many more inspections and intentions were also added to the Milestone for Spring, HTML, Ant and many others.


New Inspections

Inspection Brief Description
Comparable implemented but ‘equals()’ not overridden Classes with implement Comparable but do not override equals() can cause some surprising behavior. For example adding an object of such a class to a SortedSet will break the contract of the set, because that is defined in terms of equals().
Manual array to collection copy Copying an array into a collection using a for loop can be quite verbose. A simple list.addAll(Arrays.asList(array)) can do the trick in one relatively short expression.
‘indexOf()’ expression replacable by ‘contains()’ (for java.util.List) Using indexOf() to test for the presence of an object in a list can be cumbersome. Using the contains() method leads to clearer code.
Unqualified instance field access Some coding styles prefer to qualify each instance field access with a this qualifier. Violations of the style are highlighted by this inspection.
Method with synchronized block could be synchronized method When the entire body of a method is wrapped in a synchronized block synchronizing on this, it would be less verbose to mark the method synchronized and remove the synchronized block.
Method call violates Law of Demeter The Law of Demeter is a design principle sometimes used for Object Oriented designs.
‘assertEquals()’ between objects of inconvertible types This inspection warns if assertEquals() can never succeed because the two object supplied can not be casted to each others types. This is a serious bug in a test case.
Enumeration can be iteration This inspection helps converting older code to the collections framework. Enumerations of a Vector or Hashtable can be replaced with the equivalent Iterator code, using this inspections quick fix.
‘equals()’ or ‘hashCode()’ called on java.net.URL object When the equals() or hashCode() methods are called on a java.net.URL object, it will iniate a DNS lookup. This can be very time consuming and lead to performance issues.
Map or Set may contain java.net.URL objects Map or Set implementations use the equals() and
hashCode() methods to add and retrieve their contents. When the Map or Set contain URL objects, this will result in expensive DNS lookups.
Number comparison using ‘==’ instead of ‘equals()’ A special case of the already existing “Object comparison using ‘==’ instead of ‘equals()’. This can be an extra serious problem for Numbers since autoboxing was introduced in Java 5. Small values of Integers are cached for example, which can lead to hard to predict success and failures of == comparisons.
Implicit call to array ‘.toString()’ When a array is appended to a string it will append the default toString() of the array object. The actual desired outcome is usually to append the contents of the array, not the array object itself. This problem is easily fixable with the included quick fix.
Suspicious indentation after control statement without braces If the statement after an if statement is indented to the same level as the if statement, it may appear as if it is part of the if statement, when in reality it is executed every time.
Unpredictable BigDecimal constructor call Constructing a new BigDecimal object using a double value, may cause rounding errors. It is better to create a new BigDecimal with a string.
Unnecessary unary minus One plus minus one, equals one minus one, which is a simpler expression



New Intentions

Intention Brief Description
Replace For Loop with While Loop Replaces a for loop with the equivalent while loop.
Replace While Loop with Do While Loop Replaces a while loop with the equivalent construct: a do-while loop surrounded by an if statement.
Replace Do While Loop with While Loop Replaces a do-while loop with an equivalent while loop construct.
Replace Operator Assignment with Assignment For example i += 1 becomes i = i + 1
Replace Catch Section with Throws Declaration Removes the catch section and adds a throws declaration to the surrounding method.
Wrap Vararg Arguments with Explicit Array Creation This intention makes the array in a variable argument method call explicit. Useful when the array has to be extracted to a variable.
Replace For-each Loop with Indexed For Loop
and
Replace For-each Loop with Iterator For Loop
These two replace the “Replace For-each Loop with Old Style For Loop” intention in IntelliJ IDEA 6, which was more limited. The first intention replaces a foreach loop, which iterates over an array or list, with an indexed for-loop. The second replaces a foreach loop, which iterates over a collection object with an iterator for-loop construct.



Furthermore, in this Milestone release many improvements and bug fixes were introduced to InspectionGadgets and IntentionPowerPack, making intentions and inspections applicable in wider range of cases; new quick fixes were added and documentation was also improved.


Download the Milestone release to give the new and improved features a try.


Read more about new features and improvements.

Technorati tags: , , , ,

Running Mustang

Thursday, August 17th, 2006

These days I am running a beta of IntelliJ IDEA on a preview release of JDK 1.6.0 (also known as Mustang). Because I use both in my daily work and play, I like to see how the new versions are going to be while I can still have some influence on their implementation. Here is how I do it.
Normally IntelliJ IDEA does not run on a non-supported JDK, so It is necessary to disable the JDK version checking it performs. This is done by editing the idea.properties file that can be found in the bin directory inside IDEA’s installation directory. Add the following line:
idea.no.jdk.check=true

Furthermore, the environment variable IDEA_JDK or JDK_HOME should be set to point to the location where JDK 1.6.0 is installed. This is the JDK IntelliJ IDEA will use to run itself on. If IDEA_JDK is defined, the value of that variable will be used, otherwise IntelliJ IDEA tries to use JDK_HOME. IntelliJ IDEA can now be started with the idea.bat file on Windows or idea.sh on Unix and will be running on Mustang. On the Mac the procedure is slightly different.

Let me tell you first about the bad sides to running IntelliJ IDEA on Mustang, before I get to the good parts. Disadvantage number one, it is unsupported. Any bugs you find in IntelliJ IDEA running on Mustang will most likely not be fixed. At least not before JDK 1.6.0 is released, probably in October 2006. Disadvantage number two, Mustang still has bugs. For example until Mustang build 94, which I am currently using, closing all file editor tabs needed to be avoided at all costs. An exception was thrown and it was not possible anymore to open new files until IntelliJ IDEA was restarted. Currently the most serious bug I know about is slow scrolling in the IntelliJ IDEA editor and diff windows.

And now some advantages. Mustang contains a fix for the infamous “grey rect”. On Windows and Linux a Java frame is no longer cleared with a grey background every time it is obscured and revealed, but it is redrawn from a back buffer containing the frame’s previous contents. The fix has the psychological effect of making IDEA appear more responsive and it looks much better too. Mac users don’t need this fix, as any Java application already looks much better there than on the other platforms.

IntelliJ IDEA with visible gray rect problems

Another Mustang feature IntelliJ IDEA can make use of is the splash screen functionality. Mustang’s Java application launcher has a new command line option which tells it to show a splash screen image while it is starting up. This is especially nice when starting IDEA with the bat file, because the splash screen appears almost instantaneously, while using an older JDK the splash screen takes several seconds to show up.

IntelliJ IDEA logo

To use Mustang’s splash screen with IntelliJ IDEA, use a zip application to open the icons.jar file. This file can be found in the lib directory in the IntelliJ IDEA’s installation directory. Extract from this archive the file idea_logo.png and place it in the IntelliJ IDEA’s bin directory. This is the image that will be used as the splash screen. Now edit the file idea.vmoptions and add the following line:
-splash:idea_logo.png

And that is it. Start IntelliJ IDEA with idea.bat and the splash will appear immediately. After several seconds it will be replaced with the IntelliJ IDEA’s normal splash screen, which also shows you your license information.

Technorati tags:, , ,

Parentheses Inspections & Intentions

Monday, June 12th, 2006

You know the “Unnecessary Parentheses” inspection? IntelliJ IDEA has had it for quite some time. And if you were a user of the InspectionGadgets plugin since before it was bundled with IntelliJ IDEA, you know it even longer. The inspection reports any parentheses which do not alter the default evaluation order of an expression. For example:



It’s a nice inspection, but it may be a little greedy. I write code not only for the compiler, but also to be read by me and other people. Sometimes the parentheses highlighted by the inspection do have a use other than modifying the order of evaluation: they serve to clarify the expression.
Often while reading some new or old code, I encounter complex expressions which are quite hard to understand, especially so when they don’t have any parentheses to clarify the evaluation order. Take for example the following (still quite simple) code:



The new “Add Clarifying Parentheses” intention can help understand complex expressions, by adding a few well placed parentheses. This intention is available in Demetra since build #5218. While strictly unnecessary, with parentheses understanding the expression takes a little less brainpower.



I think there should be an option in the “Unnecessary Parentheses” inspection to ignore clarifying parentheses, don’t you agree?

Technorati tags: , , ,