AdSense Mobile Ad

Friday, August 19, 2011

Weird Auto ISO Behaviour on Nikon D5100 With a Hot-Shoe Mounted Flash

If you want to help me keep on writing this blog, please buy your new Nikon camera at the best price on Amazon using the link below.


ISO sensitivity is one of the three parameters, together with aperture and shutter speed, used to determine the exposure of a shot. Raising the ISO sensitivity lets the sensor react more quickly to light, thus allowing for smaller apertures or faster shutter speeds. The ISO sensitivity scale is linear: using an ISO 200 setting, for example, will have the sensor react with twice the speed than with an ISO 100. If other parameters are kept fixed, raising ISO sensitivity from 100 to 200 corresponds to a light increment of 1 stop.

The possibility of choosing an appropriate ISO sensitivity with the flick of a switch gives photographers a degree of freedom: you can maintain a fixed exposure level changing the ISO sensitivity and compensating with a corresponding aperture change or shutter speed change. It's so handy that I assigned the Fn button of my camera to ISO sensitivity, so that I can change it with just one click.

Auto ISO

To make photographers' life easier, many digital cameras offer an Auto ISO mode: the camera will automatically raise the ISO sensitivity in insufficient light conditions. Auto ISO on recent Nikon cameras works as follow:

  • The currently (manually) selected ISO sensitivity is treated as a minimum.
  • You choose a maximum ISO sensitivity.
  • You choose a minimum shutter speed.
  • When light condition is such that a shutter speed slower than the selected minimum is required, the camera will automatically increase the ISO sensitivity.
  • When the maximum ISO sensitivity is reached, the camera won't increase it further and will fall back to changing other parameters, depending on the mode you're shooting.
The good thing of this algorithm is its predictability: I turn Auto ISO on often and also made it part of a custom menu for easier access (although I'd really like to be able to assign a button to it).

Auto ISO with a Hot-Shoe Mounted Flash

The behaviour of the Auto ISO algorithm is consistent when using the camera pop-up flash in slow mode as well. Unfortunately, things are weirder when using a hot-shoe mounted flash, such as an SB-400. In this case, the camera increases the ISO sensitivity up to four times the value currently selected and won't raise it any more, even if you selected a greater maximum ISO.

Let's suppose you chose a value of 1600 ISO as maximum sensitivity and the current sensitivity is set to 100. When using a hot-shoe mounted flash, the camera will progressively increase the sensitivity up to four time the selected ISO, in this case 400, and will not increase it any more.

As far as I know, this behaviour is not documented in the camera manual and a quick Google search confirms this behaviour is known on other Nikon cameras as well.

Once you learn it, it's something you can live with. In fact, I often manually increase the ISO sensitivity so as to increase the maximum sensitivity the camera will choose. Since I'm not often using sensitivities as high as 6400 ISO, that's just a couple of button clicks away.

However, since it's undocumented behaviour, I do consider that overriding the it Auto ISO settings is no good. After all we shoot manually, although with the help of partially automated task such as this, because we're supposed to know what we're doing.

Could I quickly switch Auto ISO on and off, I'd surely shoot with manual ISO when using an external flash. Unfortunately, the Nikon D5100 won't allow you to do this easily, the quickest way being customizing your own menu; but to be fair, the reduced control customization capabilities is by far the only complaint I have about the D5100.

Update: D5100 Firmware v. 1.01

As described in a later post, the 1.01 firmware seems to fix this undocumented "feature": the Auto ISO behaviour is the same when using either the pop-up flash or a hot-shoe mounted flash.

Saturday, August 6, 2011

Atlassian JIRA v. 4.4 Has Been Released

Few days ago Atlassian released a brand new version of its flagship issue and project tracking software: JIRA v. 4.4.

Even though it's a "minor" upgrade it introduces a bunch of great new features, both for users, project administrators and JIRA administrators.

Installation


Installing and upgrading JIRA standalone has always been easy but the new installer and configuration wizard really make it trivial.

If you're going to perform a new JIRA installation, the installer now takes care of everything, including the creation of a dedicated JIRA user to the registration of JIRA as a service in the operating system. The new configuration wizard lets you configure the external database used by JIRA (are you using one, aren't you?) with a handy graphical user interface just during the installation phase. Now, manual configuration file editing and JIRA restarts are left to the geeky administrators.

If you're going to perform multiple JIRA installation, you're going to like the new unattended installation mode that brings even more enterprise-like features to JIRA. Administrators can specify installations settings for JIRA in a dedicated file that can be fed to the installer. To make things even simpler, the JIRA installer is creating one for you when you perform an interactive installation. Just take it and use it as a template: apply the modifications you need and feed it to the installer.

If you're going to perform a JIRA update, something which is very common giving the pace at which Atlassian releases JIRA updates, life's never been so easy. The installer has an update option that takes care of everything, from the backup of your JIRA home directory to the migration of the most common settings (such as web server configuration and database configuration).

User Interface Improvements

JIRA v. 4.4 introduces plenty of improvements targeted at users.


User Time Zone


If users of a single JIRA instance of yours are scattered around the globe, you're going to appreciate the new User time zone property of the user profile. Users can now specify the time zone they're working on so that other people can now what to expect when interacting with them.

User Time Zone



Workflow Viewer


Users granted the appropriate privilege can now see the current status of an issue in a workflow viewer. Users are now able to quickly and visually identify where an issue is in the workflow.

JIRA Workflow Viewer


Other Improvements


There are many other improvements available, such as:

  • New mobile-friendly email templates.
  • New defaults fields in workflow transition screen, such as Linked Issue.
  • Multiple file selection when uploading attachments.
  • JQL improvements.
  • Refurbished Activity Stream gadget.
Please read the official JIRA Release Notes for further information about this version or download a copy of JIRA and try it now.

Improvements for the Administrators

JIRA v. 4.4 introduces many interesting new features that aim to ease further the administration of JIRA and JIRA projects. The thing I like most is that Atlassian has succeeded in simplifying considerably the administration JIRA interface without losing any of the legendary JIRA configuration flexibility.

New Administration Mode

The new administration mode replaces the old administration window and its large administration panel on the left side of the window. The administrator can now enter the administration mode and use a totally new user interface. The administration mode welcomes the admin with a new dashboard-like control panel, where links to the administration windows are grouped by subject.

I really feel that this new mode, beyond the eye candy of the new windows, provides a feeling of order and clarity that the old administration window was losing over time under the weight of more and more menu items.

Workflow Designer

This is a groundbreaking feature many, many administrators are going to love. Simply.

Up to JIRA 4.3, administrators had to define workflows on tabular views, defining the states of the finite state machine and the transaction between them. Looking at a workflow was not possible, the only way being using pencil and paper to draw the finite state machine. The configuration was somewhat cumbersome, although quite clear with respect to other implementations I've seen.

With JIRA 4.4, administrators can now define a workflow using a graphical user interface. Drawing the state machine has never been so easy and I expect that workflow implementation and maintenance costs are going to fall heavily with this new tool.

JIRA Workflow Designer

Improved Project-Centric Administration

JIRA powerful and flexible configuration features always come with some costs: administrators had to fully understand what JIRA schemes are and how they are supposed to be used. The old JIRA configuration interface was schema-centric and sometimes it could be difficult to easily grasp which scheme was supposed to be changed to apply the desired configuration in a project.

Things have changed with JIRA 4.4. The new JIRA configuration interface is project-centric: it combines the power provided by JIRA schemes with an easy user interface that helps the administrator perform his tasks, guiding him through the various configuration steps, always starting from a project administration window.


Conclusions

In my opinion, this is one of the biggest JIRA updates in the recent years. If you think that this is just a minor upgrade, I'm sure you'd be surprised to discover that you're wrong: maybe such an upgrade would have deserved a major version upgrade.

Impressions were overall good. I was pleased to discover that I had not to go through diff-ing configuration files to migrate the Tomcat and database configuration from the old to the new JIRA instance: not only the odds of making a mistake are dumped to zero, but the already short time required to update JIRA has been almost zeroed as well.

Both users and admins are going to love the new features introduced with this versions. I sincerely expect that administrators productivity is going to increase, as well as their "disposition" to accept user customization requests for their projects. Customizing JIRA has never been so easy and the new designer brings a totally new way to define new workflows and maintain existing ones.

That's pretty more to it than this, and the best thing you can do is do a JIRA test drive yourself. Here are the complete JIRA 4.4 Release Notes and here's where you can download JIRA and try it yourself.

Sunday, March 27, 2011

Wrapping ReCaptcha in a Custom JSF Component (With Facelets Support)

A couple of days ago I decided to protect a form in a web application of ours with a CAPTCHA and, after spending some hours evaluating the available options, I chose Google's reCaptcha.

Since the form I had to protect is presented by a Java EE 6 Web Module using Facelets, I decided that the best course of action was:
  • Using a reCaptcha Java library, as suggested by the reCaptcha developer's documentation.
  • Wrapping the library functionality into a custom JSF component, so that it could be easily reused in any Java EE web application.
  • Writing a Facelets tag library descriptor so that I could use my component from both JSP and Facelets pages.
Please beware that, for the sake of clarity, some error management and logging code has been omitted from the examples below. 

    reCaptcha Java Library

    The contributed reCaptcha Java library described in the reCaptcha developer's documentation is really easy to use but it does not offer the adequate tools that a Java EE developer needs. To summarize, it requires you to add Java scriptlets into a JSP page, something awful to see and awkward to maintain.

    With this code you can create your reCaptcha instance:

    ReCaptcha c = ReCaptchaFactory.newReCaptcha("your_public_key", "your_private_key", false);

    and with the createRecaptchaHtml method you can have it create the required HTML to show the reCaptcha widget:

    c.createRecaptchaHtml(null, null);

    Once the client submits the form where the widget is shown, the following piece of code can be used to determine whether the value introduced by the user is correct or not:

    String remoteAddr = request.getRemoteAddr();
    ReCaptchaImpl reCaptcha = new ReCaptchaImpl();
    reCaptcha.setPrivateKey("your_private_key");

    String challenge = request.getParameter("recaptcha_challenge_field");
    String uresponse = request.getParameter("recaptcha_response_field");
    ReCaptchaResponse reCaptchaResponse = reCaptcha.checkAnswer(remoteAddr, challenge, uresponse);

    reCaptchaResponse.isValid();

    No doubt a custom tag would be much easier to use.

    A reCaptcha Custom Tag

    We would like to be able to write something like this in our pages, instead:

    <rc:recaptcha ... />

    The required parameters that the library needs are the two reCaptcha keys, so our custom tag would end up like:

    <rc:recaptcha id="..." publicKey="..." privateKey="..." />

    The basics files you need to build a custom JSF components are:
    • The component implementation file.
    • The component's renderer.
    • The component's tag handler.

    The Component

    Since users will input data through the component, our component class will extend the JSF UIInput class. Although we won't ever read what the user inputs, we use this class so that we can take advantage of the JSF infrastructure during the validation phase.

    Into our component skeleton, we create the setter methods so that the reCaptcha keys can be configured:

    public class RecaptchaComponent extends UIInput {

      static final String RecaptchaComponent_FAMILY = "RecaptchaComponentFamily";
      private String publicKey;
      private String privateKey;

      @Override
      public final String getFamily() {
        return RecaptchaComponent_FAMILY;
      }

      public void setPublicKey(String s) {
        publicKey = s;
      }

      public void setPrivateKey(String s) {
        privateKey = s;
      }

      public String getPublicKey() {
        if (publicKey != null)
          return publicKey;
           
        ValueExpression ve = this.getValueExpression("publicKey");
        if (ve != null) {
          return (String)ve.getValue(getFacesContext().getELContext());
        } else {
          return publicKey;
        }
      }

      public String getPrivateKey() {
        if (privateKey != null)
          return privateKey;

        ValueExpression ve = this.getValueExpression("privateKey");
        if (ve != null) {
          return (String)ve.getValue(getFacesContext().getELContext());
        } else {
          return privateKey;
        }
      }
    }

    As you may notice, since we want to accept EL expressions to set the reCaptcha keys, the corresponding getters take that into account and retrieve the value from a value expression if the user didn't use a literal.

    The Renderer

    The component renderer is pretty simple, since the HTML will be produced by the reCaptcha Java library:

    public class RecaptchaComponentRenderer extends Renderer {

      static final String RENDERERTYPE = "RecaptchaComponentRenderer";

      @Override
      public void decode(FacesContext context,
        UIComponent component) {
        if (component instanceof UIInput) {
          UIInput input = (UIInput) component;
          String clientId = input.getClientId(context);

          Map requestMap =
            context.getExternalContext().getRequestParameterMap();
          String newValue = (String) requestMap.get(clientId);
          if (null != newValue) {
            input.setSubmittedValue(newValue);
          }
        }
      }

      @Override
      public void encodeBegin(FacesContext ctx,
        UIComponent component) throws IOException {
      }

      @Override
      public void encodeEnd(FacesContext ctx,
        UIComponent component)
        throws IOException {
       
        if (component instanceof RecaptchaComponent) {       
          RecaptchaComponent rc = (RecaptchaComponent) component;
          String publicKey = rc.getPublicKey();
          String privateKey = rc.getPrivateKey();
          if (publicKey == null || privateKey == null) {
            throw new IllegalArgumentException("reCaptcha keys cannot be null. This is probably a component bug.");
          }

          ReCaptcha c = ReCaptchaFactory.newReCaptcha(publicKey, privateKey, false);
          String createRecaptchaHtml = c.createRecaptchaHtml(null, null);
          ResponseWriter writer = ctx.getResponseWriter();
          writer.write(createRecaptchaHtml);
        }
      }
    }

    The Component Tag Handler

    You can think of the tag handler as the intermediary between the custom tag you use in the page and the component class. It is basically responsible for getting and setting the component's properties.

    In this case, we will need the two setters to retrieve the reCaptcha keys and they must accept a ValueExpression object. When the tag handler sets the component's properties, it will check if the value are literals or value expressions and act accordingly:
    • If they're literals, it will set them into the components fields.
    • If they're value expressions, it will store them into the map of value expressions of the component for later evaluation (as seen in the component's code).

    The code will be such as:

    public class RecaptchaComponentTag extends UIComponentELTag {
      private ValueExpression publicKey;
      private ValueExpression privateKey;

      public void setPublicKey(ValueExpression s) {
        publicKey = s;
      }

      public void setPrivateKey(ValueExpression s) {
        privateKey = s;
      }

      @Override
      public String getComponentType() {
        return RecaptchaComponent.RecaptchaComponent_FAMILY;
      }

      @Override
      public String getRendererType() {
        return RecaptchaComponentRenderer.RENDERERTYPE;
      }

      @Override
      protected void setProperties(UIComponent component) {
        super.setProperties(component);
     
        if (component instanceof RecaptchaComponent) {
          RecaptchaComponent c = (RecaptchaComponent) component;

          if (publicKey != null) {
            if (publicKey.isLiteralText()) {
              c.setPublicKey(publicKey.getExpressionString());
            } else {
              c.setValueExpression("publicKey", publicKey);
            }
          }

          if (privateKey != null) {
            if (privateKey.isLiteralText()) {                
              c.setPrivateKey(privateKey.getExpressionString());
            } else {
              c.setValueExpression("privateKey", privateKey);
            }
          }
        }
      }
    }

    The Validator

    When the user submits the form, we need to check if the value he entered was correct or not. JSF input components undergo a validation phase during their life cycle, so that we can perform the reCaptcha validation during this phase.

    To do that, we need an instance of the Validator class and implement the validate method accordingly:

    public class RecaptchaValidator implements Validator {

      public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
        HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();

        if (component instanceof RecaptchaComponent) {
          RecaptchaComponent c = (RecaptchaComponent)component;
          String remoteAddr = request.getRemoteAddr();
          ReCaptchaImpl reCaptcha = new ReCaptchaImpl();
          reCaptcha.setPrivateKey(c.getPrivateKey());

          String challenge =
            request.getParameter("recaptcha_challenge_field");
          String uresponse =
            request.getParameter("recaptcha_response_field");
          ReCaptchaResponse reCaptchaResponse =
            reCaptcha.checkAnswer(remoteAddr, challenge, uresponse);

          if (!reCaptchaResponse.isValid()) {
            throw new ValidatorException(
              new FacesMessage(FacesMessage.SEVERITY_ERROR, "Invalid captcha", "Invalid captcha"));
          }
        }
      }
    }

    As it can be seen, we just use the reCaptcha Java library code to perform the check.

    Use the Validator Into the Component

    To use the validator as a default validator, we can simply add it to the list of validator of our component during the component creation:

    public RecaptchaComponent() {
        super();
        addValidator(new RecaptchaValidator());
    }

    Also, we need to override the UIInput validate method so that our validator be called;

    @Override
    public void validate(FacesContext ctx) {
      Validator[] validators = getValidators();
      for (Validator v : validators) {
        try {
          v.validate(ctx, this, null);
        } catch (ValidatorException ex) {
          setValid(false);
          FacesMessage message = ex.getFacesMessage();
          if (message != null) {
            message.setSeverity(FacesMessage.SEVERITY_ERROR);
            ctx.addMessage(getClientId(ctx), message);
          }
        }

        super.validate(ctx);
      }
    }

    The JSF Configuration File

    We now must tell JSF about this new component. Since we distribute it into a standalone JAR, we add a faces-config.xml file into the META-INF directory of the archive with this content:

    <?xml version='1.0' encoding='UTF-8'?>
    <faces-config version="2.0"
      xmlns="http://java.sun.com/xml/ns/javaee"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd">
      <component>
        <component-type>RecaptchaComponentFamily</component-type>
        <component-class>es.trafico.jsf.component.RecaptchaComponent</component-class>
      </component>

      <render-kit>
        <renderer>
          <description>Renderer.</description>
          <component-family>RecaptchaComponentFamily</component-family>
          <renderer-type>RecaptchaComponentRenderer</renderer-type>
          <renderer-class>
            es.trafico.jsf.component.RecaptchaComponentRenderer
          </renderer-class>
        </renderer>
      </render-kit>

      <validator>
        <validator-id>recaptchaValidator</validator-id>
        <validator-class>
          es.trafico.jsf.component.RecaptchaValidator
        </validator-class>
      </validator>
      
    </faces-config>

    The Tag Library Descriptor

    To be able to use our new custom component in our JSP pages, we need a tag library descriptor. Since we're packaging our custom component in a standalone JAR file so that it can be used in all our applications, the tag library descriptor must be placed into the META-INF directory of the archive.

    Our taglib.tld file is like this:

    <?xml version="1.0" encoding="UTF-8"?>
    <taglib version="2.1" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd">
      <tlib-version>1.0</tlib-version>
      <short-name>ReCaptcha-Library</short-name>
      <uri>http://www.reacciona.es/rc</uri>

      <tag>
        <name>recaptcha</name>
        <tag-class>
          es.trafico.jsf.component.RecaptchaComponentTag
        </tag-class>
        <body-content>empty</body-content>
        <attribute>
          <name>id</name>
          <required>false</required>
          <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
          <name>publicKey</name>
          <required>true</required>
          <deferred-value>
            <type>java.lang.String</type>
          </deferred-value>
        </attribute>
        <attribute>
          <name>privateKey</name>
          <required>true</required>
          <deferred-value>
            <type>java.lang.String</type>
          </deferred-value>
        </attribute>
      </tag>
    </taglib>

    Using The Component

    You can now use your new tag library in your JSP page adding this directory at the beginning of the page:

    <%@taglib prefix="rc" uri="http://www.reacciona.es/rc"%>

    You can now add your custom component instances into your JSP pages (with JSF) this way:

    <f:view>
    ...
      <h:form>
        <rc:recaptcha id="rc"
          publicKey="#{yourBean.publicKey}"
          privateKey="#{yourBean.privateKey}"/>
        <h:message for="rc" />
      </h:form>
    </f:view>

    In this example, we use a value expression to set both the reCaptcha keys using two properties of a managed bean of yours. This way, you won't hardcode any parameter into your pages.

    Using the Custom Component With Facelets

    You won't be able to use the custom component into a Facelets page until you write a Facelets tag library descriptor. You might be wondering why so many indirection layers: Facelets is designed to be more flexible than JSP and its tag descriptors reflect this design decision. Instead of having to describe your component down to the smallest detail, Facelets lets your just declare its existence and, for example, will set attributes at runtime, inspecting the component and tag classes.

    A basic Facelets tag library descriptor for the component is the following:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE facelet-taglib PUBLIC
      "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN"
      "http://java.sun.com/dtd/facelet-taglib_1_0.dtd">

    <facelet-taglib>
      <namespace>http://www.reacciona.es/rc</namespace>
      <tag>
        <tag-name>recaptcha</tag-name>
        <component>
          <component-type>RecaptchaComponentFamily</component-type>
          <renderer-type>RecaptchaComponentRenderer</renderer-type>
        </component>
      </tag>
    </facelet-taglib>

    Please note that both the component and the renderer type are just the identifiers we declared in the JSF configuration file.

    We can now use the custom component into a Facelets page adding the following namespace into the html tag at the beginning of the page:

    xmlns:rc="http://www.reacciona.es/rc"

    The syntax to add the component is the same syntax that we used in the JSP example.

    Saturday, March 26, 2011

    Java Generics Tutorial - Part II - Subtyping

    Part I - The Basics
    Part II - Subtyping
    Part III - Wildcards
    Part IV - Bounded Type Variables

    In Part I we quickly explored the basics of Java generics. In this blog post we will explore how generic types behave in the Java type system.

    Subtypes

    In Java, as in other object-oriented typed languages, hierarchies of types can be built:



    In Java, a subtype of a type T is either a type that extends T or a type that implements T (if T is an interface) directly or indirectly. Since "being subtype of" is a transitive relation, if a type A is a subtype of B and B is a subtype of C, then A will be a subtype of C too. In the figure above:
    • FujiApple is a subtype of Apple.
    • Apple is a subtype of Fruit.
    • FujiApple is a subtype of Fruit.
    Every Java type will also be subtype of Object.

    Every subtype A of a type B may be assigned to a reference of type B:

    Apple a = ...;
    Fruit f = a;

    Subtyping of Generic Types

    If a reference of an Apple instance can be assigned to a reference of a Fruit, as seen above, then what's the relation between, let's say, a List<Apple> and a List<Fruit>? Which one is a subtype of which? More generally, if a type A is a subtype of a type B, how does C<A> and C<B> relate themselves?

    Surprisingly, the answer is: in no way. In more formal words, the subtyping relation between generic types is invariant.

    This means that the following code snippet is invalid:

    List<Apple> apples = ...;
    List<Fruit> fruits = apples;

    and so does the following:

    List<Apple> apples;
    List<Fruit> fruits = ...;
    apples = fruits;

    But why? Is an apple is a fruit, a box of apples (a list) is also a box of fruits.

    In some sense, it is, but types (classes) encapsulate state and operations. What would happen if a box of apples was a box of fruits?

    List<Apple> apples = ...;
    List<Fruit> fruits = apples;
    fruits.add(new Strawberry());

    If it was, we could add other different subtypes of Fruit into the list and this must be forbidden.

    The other way round is more intuitive: a box of fruits is not a box of apples, since it may be a box (List) of other kinds (subtypes) of fruits (Fruit), such as Strawberry.

    Is It Really a Problem?

    It should not be. The strongest reason for a Java developer to be surprised is the inconsistency between the behavior of arrays and generic types. While the subtyping relations of the latter is invariant, the subtyping relation of the former is covariant: if a type A is a subtype of type B, then A[] is a subtype of B[]:

    Apple[] apples = ...;
    Fruit[] fruits = apples;

    But wait! If we repeat the argument exposed in the previous section, we might end up adding strawberries to an array of apples:

    Apple[] apples = new Apple[1];
    Fruit[] fruits = apples;
    fruits[0] = new Strawberry();

    The code indeed compiles, but the error will be raised at runtime as an ArrayStoreException. Because of this behavior of arrays, during a store operation, the Java runtime needs to check that the types are compatible. The check, obviously, also adds a performance penalty that you should be aware of.

    Once more, generics are safer to use and "correct" this type safety weakness of Java arrays.

    In the case you're now wondering why the subtyping relation for arrays is covariant, I'll give you the answer that Java Generics and Collections give: if it was invariant, there would be no way of passing a reference to an array of objects of an unknown type (without copying every time to an Object[]) to a method such as:

    void sort(Object[] o);

    With the advent of generics, this characteristics of arrays is no longer necessary (as we'll see in the next part of this post) and should indeed by avoided.

    Next Steps

    In the next post we will see how generic wildcards introduce both covariant and contravariant subtyping relations with generics.

    Part I - The Basics
    Part II - Subtyping
    Part III - Wildcards
    Part IV - Bounded Type Variables

    Java Generics Tutorial - Part III - Wildcards


    The previous posts introduced us to the basics of Java generics y their subtyping relations. In this posts we'll introduce wildcards and how can covariant and contravariant subtyping relations be established with generics.

    Wildcards

    As we've seen in the previous post, the subtyping relation of generic types is invariant. Sometimes, though, we'd like to use generic types in the same way we can use ordinary types:
    • Narrowing a reference (covariance).
    • Widening a reference (contravariance

    Covariance

    Let's suppose, for example, that we've got a set of boxes, each one of a different kind of fruit. We'd like to be able to write methods that could accept a any of them. More formally, given a subtype A of a type B, we'd like to find a way to use a reference (or a method parameter) of type C<B> that could accept instances of C<A>.

    To accomplish this task we can use a wildcard with extends, such as in the following example:

    List<Apple> apples = new ArrayList<Apple>();
    List<? extends Fruit> fruits = apples;

    ? extends reintroduces covariant subtyping for generics types: Apple is a subtype of Fruit and List<Apple> is a subtype of List<? extends Fruit>.

    Contravariance

    Let's now introduce another wildcard: ? super. Given a supertype B of a type A, then C<B> is a subtype of C<? super A>:

    List<Fruit> fruits = new ArrayList<Fruit>();
    List<? super Apple> = fruits;

    How Can Wildcards Be Used?

    Enough theory for now: how can we take advantage of these new constructs?

    ? extends
    Let's go back to the example we used in Part II when introducing Java array covariance:

    Apple[] apples = new Apple[1];
    Fruit[] fruits = apples;
    fruits[0] = new Strawberry();

    As we saw, this code compiles but results in a runtime exception when trying to add a Strawberry to an Apple array through a reference to a Fruit array.

    Now we can use wildcards to translate this code to its generic counterpart: since Apple is a subtype of Fruit, we will use the ? extends wildcard to be able to assign a reference of a List<Apple> to a reference of a List<? extends Fruit> :

    List<Apple> apples = new ArrayList<Apple>();
    List<? extends Fruit> fruits = apples;
    fruits.add(new Strawberry());

    This time, the code won't compile! The Java compiler now prevents us to add a strawberry to a list of fruits. We will detect the error at compile time and we won't even need any runtime check (such as in the case of array stores) to ensure that we're adding to the list a compatible type. The code won't compile even if we try to add a Fruit instance into the list:

    fruits.add(new Fruit());

    No way. It comes out that, indeed, you can't put anything into a structure whose type uses the ? extends wildcard.

    The reason is pretty simple, if we think about it: the ? extends T wildcard tells the compiler that we're dealing with a subtype of the type T, but we cannot know which one. Since there's no way to tell, and we need to guarantee type safety, you won't be allowed to put anything inside such a structure. On the other hand, since we know that whichever type it might be, it will be a subtype of T, we can get data out of the structure with the guarantee that it will be a T instance:

    Fruit get = fruits.get(0);

    ? super
    What's the behavior of a type that's using the ? super wildcard? Let's start with this:

    List<Fruit> fruits = new ArrayList<Fruit>();
    List<? super Apple> = fruits;

    We know that fruits is a reference to a List of something that is a supertype of Apple. Again, we cannot know which supertype it is, but we know that Apple and any of its subtypes will be assignment compatible with it. Indeed, since such an unknown type will be both an Apple and a GreenApple supertype, we can write:

    fruits.add(new Apple());
    fruits.add(new GreenApple());

    If we try to add whichever Apple supertype, the compiler will complain:

    fruits.add(new Fruit());
    fruits.add(new Object());

    Since we cannot know which supertype it is, we aren't allowed to add instances of any.

    What about getting data out of such a type? It turns out that you the only thing you can get out of it will be Object instances: since we cannot know which supertype it is, the compiler can only guarantee that it will be a reference to an Object, since Object is the supertype of any Java type.

    The Get and Put Principle or the PECS Rule

    Summarizing the behavior of the ? extends and the ? super wildcards, we draw the following conclusion:


    Use the ? extends wildcard if you need to retrieve object from a data structure.
    Use the ? super wildcard if you need to put objects in a data structure.
    If you need to do both things, don't use any wildcard.

    This is what Maurice Naftalin calls The Get and Put Principle in his Java Generics and Collections and what Joshua Bloch calls The PECS Rule in his Effective Java.

    Bloch's mnemonic, PECS, comes from "Producer Extends, Consumer Super" and is probably easier to remember and use.

    Next Steps

    In the next post (coming soon), we will put all together in some examples to clarify how generics can be used to help us write cleaner, clearer and more type safe code.

    Part I - The Basics
    Part II - Subtyping
    Part III - Wildcards
    Part IV - Bounded Type Variables