Puzzle 21: What Is my class? Lens 2
The following program is doing exactly what the previous puzzle did, but it does not assume that the slash symbol is the symbol that separates the file name component. Instead, the program uses Java.io.File.separetor, which is specified as a public string field that contains the platform-dependent file name delimiter. Does this program print the correct, platform-related class file name? The program is loaded from this class file.
Package Com.javapuzzlers;import Java.io.file;public class Metoo{public static void Main (string[] args) { System.out.println (MeToo.class.getName (). replaceall ("\ \", File.separator) + ". Class");}}
Before that, this program is not assumed that the slash symbol is the symbol separating the file name component, so this program will show one of two behaviors depending on the underlying platform. If the slash is a file delimiter (for example, in Unix), then the program prints com/javapuzzlers. Metoo.class, that's right. If the backslash is the file delimiter (for example, in Windows), the program will have an exception and print something like this:
Exception in thread "main" stringindexoutofboundsexception:string index out of Range:1at java.lang.String.charAt ( string.java:558) at Java.util.regex.Matcher.appendReplacement (mather.java:696) at Java.util.regex.Matcher.replaceAll (mather.java:806) at Java.lang.String.replaceAll (string.java:2000) at Com.javapuzzlers.MeToo.main (Metoo.java:6)
Although this behavior is platform-related, it is not what we expect. Why is there an error on Windows, and what is wrong with it? From the exception printed above, we can tell that there is an exception in line 5th of the program. It turns out that the second parameter of String.replaceall is not an ordinary string, but rather an alternative string, as defined in the Java.util.regex specification. A backslash that appears in an alternate string escapes the character immediately following it, causing it to be processed literally. When you run the program on Windows, the substitution string is a separate backslash, and it is not valid. So, what should be done to solve this problem? The 5.0 release provides not one but two new ways to solve it. The first method is java.util.regex.Matcher.quoteReplacement, which converts a string into a corresponding substitution string. As follows:
System.out.println (MeToo.class.getName (). replaceall ("\ \", Matcher.quotereplacement (file.separator)) + ". Class");
Then the second method provides a better solution, the method is String.Replace (charsequence,charsequence), It does the same thing as String.replaceall, but it treats patterns and substitutes as string literal constants. As follows:
System.out.println (MeToo.class.getName (). Replace (".", File.separator) + ". Class");
But what if you're using an earlier version of Java? That can only be done without using regular expressions at all, and using String.Replace (Char,char) may be easier:
System.out.println (MeToo.class.getName (). replace ('. ', File.separatorchar) + ". Class");
So from this puzzle and the previous puzzle, we learned to be careful when using unfamiliar class library methods. When you have doubts, you need to turn to Javadoc. In addition, regular expressions are tricky, and the problems they cause tend to be exposed at run time rather than at compile time.
Java Puzzle characters (puzzle 21)