Home arrow Java arrow Page 5 - Conversions and Java Print Streams
JAVA

Conversions and Java Print Streams


In the conclusion to this three-part article, we'll discuss data and time conversions, character conversions, and more. This article is excerpted from chapter seven of Java I/O, Second Edition, written by Elliotte Rusty Harold (O'Reilly, 2006; ISBN: 0596527500). Copyright © 2006 O'Reilly Media, Inc. All rights reserved. Used with permission from the publisher. Available from booksellers or direct from O'Reilly Media.

Author Info:
By: O'Reilly Media
Rating: 5 stars5 stars5 stars5 stars5 stars / 12
June 28, 2007
TABLE OF CONTENTS:
  1. · Conversions and Java Print Streams
  2. · Character conversions
  3. · Format Modifiers
  4. · Flags
  5. · Precision

print this article
SEARCH DEVARTICLES

Conversions and Java Print Streams - Precision
(Page 5 of 5 )

 

Floating-point types (%e, %E, %f, %g, and%G) may also specify a precision in the form.3or.5. The precision comes after the width but before the conversion code. This indicates how many places are used after the decimal point. For example, this statement formats the same five constants 15 places wide, with 3 places after the decimal point:

  System.out.printf("%15.3f %15.3f %15.3f
%15.3f %15.3f",
                    Math.PI, Math.E, 1.0, 0.0, Math.sqrt(2));

This is the output:

3.142   2.718   1.000   0.000   1.414

A precision can also be applied to strings and other nonnumeric, nondate types. In these cases, it specifies the maximum number of characters to write to the output.

Precision cannot be set for integral types, however. Attempting to do so throws anIllegalFormatPrecisionException. As usual, this is a subclass ofIllegalFormatExceptionand a runtime exception.

Formattable

You can format your own custom classes by implementing the Formattable interface. In format strings, you use %s and %S to indicate where you want your custom class instances placed. The default formatting for objects matched to %s and %S is simply whatever is returned by toString(). However, more often than not, this is just a debugging string not really meant for display to end users. If your class implements the java.util.Formattable interface, Java will use the return value of the object’s formatTo() method instead. That method has this signature:

  public void formatTo(Formatter formatter, int flags, int width, int precision)

The four arguments are:

formatter

TheFormatterthat calledformatTo. More importantly, this is the object onto which the output will be written. Your method will invoke this object’sformat() methods to write to the underlying stream.

flags

A bitmasked constant providing the values of various flags set for this operation:
^,-,#, etc. You interpret these with theFormattableFlagsclass.

width

The minimum number of characters your method must return. If the returned value has fewer characters than the specified minimum, it will be padded with spaces.

precision

The maximum number of characters your method should return.

Earlier, I complained that the uppercasing in theURLclass was too naïve because, when formatted, it changed the case of case-sensitive parts such as the path and the query string as well as case-insensitive parts such as the scheme and the hostname. There’s another problem with the naïve uppercasing: the scheme and hostnames are defined in ASCII, but uppercasing isn’t always. In particular, uppercasing the letter i in Turkey produces the capital dotted I rather than the usual undotted capital I. For instance, www.microsoft.com uppercases as WWW.MICROSOFT.COM, which will not resolve.

Example 7-5 demonstrates aFormattableURLclass that uppercases only those parts of a URL that can be uppercased without changing its meaning. Ideally this would be a subclass ofjava.net.URL, but sinceURL is final, delegation is used instead. In essence,FormattableURLis a wrapper around a URL object that just provides theformatTo()method.

Example 7-5.  Implementing Formattable

import java.util.*;
import java.net.*;
public class FormattableURL implements Formattable {

  private URL delegate;

  public FormattableURL(URL url){
    this.delegate = url;
  }

  public void formatTo(Formatter formatter, int flags, int width,
      int precision) {

    if (precision < -1) {
     
throw new IllegalFormatPrecisionException(precision);
    }
    if (width < -1) {
     
throw new IllegalFormatWidthException(width);
    }
    if (precision > width) {
     
throw new IllegalFormatPrecisionException(precision);
    }

    // Check to see if we've been asked to use any flags we don't interpret
    int recognizedFlags
   
= FormattableFlags.UPPERCASE | FormattableFlags.LEFT_JUSTIFY;
    boolean unsupportedFlags = ((~recognizedFlags) & flags) != 0;
    if (unsupportedFlags) {
     
// We should really pass the flags to this constructor.
      // However, Java doesn't offer any reasonable way to get these.
      throw new IllegalFormatFlagsException("#");
   
}

    boolean upperCase = (flags & FormattableFlags.UPPERCASE) != 0;

    StringBuffer sb = new StringBuffer();

    String scheme = delegate.getProtocol();
    if (upperCase && scheme != null) {
      scheme = scheme.toUpperCase(Locale.ENGLISH);
    }

    String hostname = delegate.getHost();
    if (upperCase && hostname != null) {
      hostname = hostname.toUpperCase(Locale.ENGLISH);
    }

    String userInfo = delegate.getUserInfo();

    int port = delegate.getPort();
    String path = delegate.getPath();
    String query = delegate.getQuery(); String fragment = delegate.getRef();
    if (scheme != null) {
      sb.append(scheme);
      sb.append("://");
   
}

    if (userInfo != null) {
      sb.append(userInfo);
      sb.append("@");
   
}

    if (hostname != null) {
      sb.append(hostname);
    }

    if (port != -1) {
      sb.append(':');
      sb.append(port);
   
}

    if (path != null) {
      sb.append(path);
    }

    if (query != null) {
      sb.append('?');
      sb.append(query);
   
}

    if (fragment != null) {
      sb.append('#');
      sb.append(fragment);
   
}

    boolean leftJustify = (flags & FormattableFlags.LEFT_JUSTIFY) != 0;

    // Truncate on the right if necessary
   
if (precision < sb.length()) {
      sb.setLength(precision);
    }
    else {// Pad with spaces if necessary
      while (sb.length() < width) {
        if (leftJustify) sb.append(' ');
        else sb.insert(0, ' ');
      }
   
}

    formatter.format(sb.toString());
  }
}

TheformatTo()method first checks to see if the values passed make sense—that is, that the width is greater than or equal to the precision, and both are greater than or equal to –1. (–1 simply indicates that these values weren’t set.) Assuming these checks pass, it splits the delegate URL into its component parts and uppercases the two case-insensitive parts (the scheme and the hostname) if the uppercase flag is set. It then appends all the other parts without changing their cases at all. Finally, if the precision is less than the string’s length, the formatted string is truncated on the right. If the string’s length is less than the specified width, the string is padded with spaces: on the right by default but on the left if the left-justified flag is set. If any other flags are present, anIllegalFormatFlagsExceptionis thrown. Thus, it becomes possible to format a URL like this:

  URL url = new URL(http://www.example.org/index.html?name=value#Fred);
  System.out.printf("%60.40S\n", new FormattableURL(url));


* XML is a notable exception here. It treats linefeeds, carriage returns, and carriage return linefeed pairs equally.


DISCLAIMER: The content provided in this article is not warranted or guaranteed by Developer Shed, Inc. The content provided is intended for entertainment and/or educational purposes in order to introduce to the reader key ideas, concepts, and/or product reviews. As such it is incumbent upon the reader to employ real-world tactics for security and implementation of best practices. We are not liable for any negative consequences that may result from implementing any information covered in our articles or tutorials. If this is a hardware review, it is not recommended to open and/or modify your hardware.

blog comments powered by Disqus
JAVA ARTICLES

- Java Too Insecure, Says Microsoft Researcher
- Google Beats Oracle in Java Ruling
- Deploying Multiple Java Applets as One
- Deploying Java Applets
- Understanding Deployment Frameworks
- Database Programming in Java Using JDBC
- Extension Interfaces and SAX
- Entities, Handlers and SAX
- Advanced SAX
- Conversions and Java Print Streams
- Formatters and Java Print Streams
- Java Print Streams
- Wildcards, Arrays, and Generics in Java
- Wildcards and Generic Methods in Java
- Finishing the Project: Java Web Development ...

Watch our Tech Videos 
Dev Articles Forums 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Contact Us 
Site Map 
Privacy Policy 
Support 

Developer Shed Affiliates

 




© 2003-2017 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap
Popular Web Development Topics
All Web Development Tutorials