I'm interested in becoming more fluent in Java so I have been going through Sun/Oracle's java tutorial. I'm on the section of implementing interfaces and I do not understand the code they have given as a solution to one of the exercises.
The exercise was to implement the java.lang.CharSequence interface, the implementation should return the string backwards, and to write a small main method to test your class; make sure to call all four methods.
This was a a little overwhelming so I began to work through their solution to see if I could understand the concepts and their code. Here are my questions:
1) When they implement the charAt
method, the are returning an invocation of the charAt
method, why doesn't this cause some sort of infinite loop?
Thanks in advance.
Here is the code:
/* Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved. */
// CharSequenceDemo presents a String value -- backwards.
public class CharSequenceDemo implements CharSequence {
private String s;
public CharSequenceDemo(String s) {
//It would be much more efficient to just reverse the string
//in the constructor. But a lot less fun!
this.s = s;
}
//If the string is backwards, the end is the beginning!
private int fromEnd(int i) {
return s.length() - 1 - i;
}
public char charAt(int i) {
if ((i < 0) || (i >= s.length())) {
throw new StringIndexOutOfBoundsException(i);
}
return s.charAt(fromEnd(i));
}
public int length() {
return s.length();
}
public CharSequence subSequence(int start, int end) {
if (start < 0) {
throw new StringIndexOutOfBoundsException(start);
}
if (end > s.length()) {
throw new StringIndexOutOfBoundsException(end);
}
if (start > end) {
throw new StringIndexOutOfBoundsException(start - end);
}
StringBuilder sub =
new StringBuilder(s.subSequence(fromEnd(end), fromEnd(start)));
return sub.reverse();
}
public String toString() {
StringBuilder s = new StringBuilder(this.s);
return s.reverse().toString();
}
//Random int from 0 to max.
private static int random(int max) {
return (int) Math.round(Math.random() * max + 0.5);
}
public static void main(String[] args) {
CharSequenceDemo s =
new CharSequenceDemo("Write a class that implements the CharSequence interface found in the java.lang package.");
//exercise charAt() and length()
for (int i = 0; i < s.length(); i++) {
System.out.println(s.charAt(i));
}
//exercise subSequence() and length();
int start = random(s.length() - 1);
int end = random(s.length() - 1 - start) + start;
System.out.println(s.subSequence(start, end));
//exercise toString();
Syst开发者_JS百科em.out.println(s);
}
}
The nested call to charAt is to s.charAt which means you are invoking the same method but on another object. No infinite loop there.
Their fromEnd is defined as
private int fromEnd(int i) {
return s.length() - 1 - i;
}
almost at the top.
1) When they implement the charAt method, the are returning an invocation of the charAt method, why doesn't this cause some sort of infinite loop?
There's no infinite loop because the methods refer to two entirely different objects.
The interface defines the charAt()
signature for a CharSequence. The implementation in this case has a backing String instance. The implementation for the CharSequence calls the charAt()
method for the backing String instance. No infinite loop, because it's not calling this.charAt()
.
- The
charAt
is not actually recursive, it is calling thecharAt
method of theString
class forString s
. fromEnd(i)
is a method call to thefromEnd(int i)
method that is also defined in your class
-
//If the string is backwards, the end is the beginning!
private int fromEnd(int i) {
return s.length() - 1 - i;
}
精彩评论