<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Todd Schiller - Hungarian Notation</title><link href="https://toddschiller.com/" rel="alternate"></link><link href="https://toddschiller.com/feeds/tag/hungarian-notation.atom.xml" rel="self"></link><id>https://toddschiller.com/</id><updated>2014-12-08T00:00:00-05:00</updated><subtitle>Human ✘ Artificial Intelligence</subtitle><entry><title>Making Wrong Code... Wrong</title><link href="https://toddschiller.com/blog/java-hungarian-notation-checker.html" rel="alternate"></link><published>2014-12-08T00:00:00-05:00</published><updated>2014-12-08T00:00:00-05:00</updated><author><name>Todd Schiller</name></author><id>tag:toddschiller.com,2014-12-08:/blog/java-hungarian-notation-checker.html</id><summary type="html">&lt;p&gt;Joel Spolsky has a popular post from 2005 on
&amp;quot;&lt;a href="http://www.joelonsoftware.com/articles/Wrong.html"&gt;Making Wrong Code Look Wrong&lt;/a&gt;&amp;quot;.
In this post, I'll address his suggestion to use
&lt;a href="https://en.wikipedia.org/wiki/Hungarian_notation"&gt;Hungarian Notation&lt;/a&gt;.
It turns out we can now do better: we can make wrong code... &lt;em&gt;wrong!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Hungarian Notation is a naming scheme that conveys information about
methods …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Joel Spolsky has a popular post from 2005 on
&amp;quot;&lt;a href="http://www.joelonsoftware.com/articles/Wrong.html"&gt;Making Wrong Code Look Wrong&lt;/a&gt;&amp;quot;.
In this post, I'll address his suggestion to use
&lt;a href="https://en.wikipedia.org/wiki/Hungarian_notation"&gt;Hungarian Notation&lt;/a&gt;.
It turns out we can now do better: we can make wrong code... &lt;em&gt;wrong!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Hungarian Notation is a naming scheme that conveys information about
methods and variables. For example, we might use the prefix &amp;quot;us&amp;quot; to
denote variables that hold unsafe values, e.g., user input. This
notation makes it easy to notice the
&lt;a href="https://en.wikipedia.org/wiki/SQL_injection"&gt;SQL injection&lt;/a&gt;
vulnerability in the following code:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;usUser&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;getUserInput&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;executeSqlQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;SELECT * FROM users WHERE user=&amp;#39;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;usUser&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;#39;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The problem with Hungarian Notation is that you still have to manually
inspect the code. For real projects, manual inspection is insufficient
because of overloading, overridding, threading, version control
merges, etc. Testing is also insufficient because it can
&lt;a href="ttps://www.cs.utexas.edu/users/EWD/transcriptions/EWD02xx/EWD268.html"&gt;&amp;quot;show the presence of bugs, but never show their absence.&amp;quot;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Type Qualifiers&lt;/h2&gt;
&lt;p&gt;Hungarian Notation typically doesn't convey arbitrary information
about a variable/parameter. Rather, the notation describes the set of
values an expression may or may not have. In the example above, the
&amp;quot;us&amp;quot; prefix tells us that &lt;code&gt;usUser&lt;/code&gt; is not just a &lt;code&gt;String&lt;/code&gt;, but a
&lt;em&gt;potentially unsafe&lt;/em&gt; &lt;code&gt;String&lt;/code&gt;. The prefix is &amp;quot;qualifying&amp;quot; the
variable's type.&lt;/p&gt;
&lt;p&gt;Java 8 brought language support for user-defined Type
Qualifiers. Instead of using naming schemes, we can now define custom
Type Qualifiers that we can use in method signatures:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;executeSqlQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@Safe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Unsafe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;getUserInput&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and method bodies:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nd"&gt;@Unsafe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;usUser&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;getUserInput&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;executeSqlQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;SELECT * FROM users WHERE user=&amp;#39;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;usUser&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;#39;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Enforcing Type Qualifiers&lt;/h2&gt;
&lt;p&gt;Type Qualifiers are easier to read than Hungarian Notation because you
don't have to parse (possibly multiple) prefixes and suffixes. In some
cases, however, Type Qualifiers are harder to reason about. Using
Type Qualifiers, the qualifier is typically only written on
declarations. Using Hungarian Notation, the qualifier appears at every
occurence of the variable.&lt;/p&gt;
&lt;p&gt;Luckily, there are tools that can reason about Type Qualifiers for us,
just like the Java compiler reasons about types. One such tool is the
&lt;a href="http://checkerframework.org"&gt;Checker Framework&lt;/a&gt;. Using the Checker
Framework, we can define a checker that issues a warning wherever an
&lt;code&gt;@Unsafe&lt;/code&gt; expression is used where a &lt;code&gt;@Safe&lt;/code&gt; expression is
required. It's as simple as telling the Checker Framework that &lt;code&gt;@Safe&lt;/code&gt;
is a subtype of &lt;code&gt;@Unsafe&lt;/code&gt; — a safe value can be used wherever an
&lt;code&gt;@Unsafe&lt;/code&gt; value is expected, but not vice versa:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nd"&gt;@TypeQualifier&lt;/span&gt;
&lt;span class="nd"&gt;@SubtypeOf&lt;/span&gt;&lt;span class="p"&gt;({})&lt;/span&gt;
&lt;span class="nd"&gt;@DefaultQualifierInHierarchy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// By default, expressions are potentially unsafe&lt;/span&gt;
&lt;span class="nd"&gt;@Target&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ElementType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TYPE_USE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ElementType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TYPE_PARAMETER&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@interface&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Unsafe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nd"&gt;@TypeQualifier&lt;/span&gt;
&lt;span class="nd"&gt;@SubtypeOf&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Unsafe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// @Safe is a subtype of @Unsafe&lt;/span&gt;
&lt;span class="nd"&gt;@Target&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ElementType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TYPE_USE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ElementType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TYPE_PARAMETER&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@interface&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Safe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;What makes the Checker Framework particularly effective is its
flow-sensitivity. Checkers can reason about the type of a variable
throughout the method:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;getUserInput&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// WARNING: user is known to be @Unsafe&lt;/span&gt;
&lt;span class="n"&gt;executeSqlQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;SELECT * FROM users WHERE user=&amp;#39;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;#39;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// encode has return type @Safe String&lt;/span&gt;
&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// SAFE: user is known to be @Safe&lt;/span&gt;
&lt;span class="n"&gt;executeSqlQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;SELECT * FROM users WHERE user=&amp;#39;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;#39;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In practice, flow-sensitivity means that you rarely have to annotate
local variables.&lt;/p&gt;
&lt;p&gt;For a more thorough introduction to Type Qualifiers in Java 8, check out
&lt;a href="http://www.infoq.com/articles/Type-Annotations-in-Java-8"&gt;my article on InfoQ&lt;/a&gt;
. Complete
instructions for creating your own checker can be found in the
&lt;a href="http://types.cs.washington.edu/checker-framework/current/checker-framework-manual.html#writing-a-checker"&gt;Checker Framework documentation&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Enforcing Hungarian Notation&lt;/h2&gt;
&lt;p&gt;As we've seen, Hungarian Notation and Type Qualifiers are both
techniques for qualifying types. Therefore, it should come as no
surprise that we can leverage Type Qualifiers and the Checker Framework
to automatically enforce Hungarian Notation.&lt;/p&gt;
&lt;p&gt;To do so, we just need to have the Checker Framework read names as if
we were reasoning about the code ourselves. For our running example,
we have the following &amp;quot;type introduction&amp;quot; rule:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If the name of a variable or parameter has the prefix &amp;quot;s&amp;quot;, add a
&lt;code&gt;@Safe&lt;/code&gt; annotation to its type.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;We implement the rule by adding logic to the &lt;code&gt;AnnotatedTypeFactory&lt;/code&gt;
for our checker. The following method adds the &lt;code&gt;@Safe&lt;/code&gt; qualifier to
local variables:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Pattern&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;safeRegex&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Pattern&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;s[A-Z_].*&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;AnnotationMirror&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SAFE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;AnnotationUtils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;elements&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Safe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nd"&gt;@Override&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;visitVariable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;VariableTree&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;AnnotatedTypeMirror&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;safeRegex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;matcher&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="na"&gt;matches&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;replaceAnnotation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SAFE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;super&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;visitVariable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The logic is the same for parameters and fields. You can find a full
implementation of the checker &lt;a href="https://github.com/twschiller/hungarian-checker"&gt;on GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The result is a system that combines the conciceness of Hungarian
Notation with the safety of compile-time checking:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// Parameter sQuery is given the @Safe annotation&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;executeSqlQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sQuery&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// WARNING: sUser is given the @Safe annotation&lt;/span&gt;
&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sUser&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;getUserInput&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This post demonstrated how Type Qualifiers and the Checker Framework
can enforce Hungarian Notation at compile-time. Compile-time checking
makes wrong code not just &lt;em&gt;look&lt;/em&gt; wrong, but actually wrong!&lt;/p&gt;
&lt;p&gt;The source code for the checker is available on GitHub
at: &lt;a href="https://github.com/twschiller/hungarian-checker"&gt;https://github.com/twschiller/hungarian-checker&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This post was inspired by a talk that
&lt;a href="https://en.wikipedia.org/wiki/Charles_Simonyi"&gt;Charles Simonyi&lt;/a&gt; gave
on May 10, 2012 at the University of Washington about the importance
of notation.&lt;/em&gt;&lt;/p&gt;
</content><category term="Verification"></category><category term="verification"></category><category term="java"></category><category term="Hungarian Notation"></category><category term="Checker Framework"></category></entry></feed>