Java trick question: string theory

Alonso Del Arte
2 min readJul 17, 2023

--

Photo by Edoardo Botez on Unsplash

There’s yet another silly trick question about Java making the rounds on the Internet. Before you answer it, keep in mind that sometimes the shtick of a trick question is getting you to assume something that is not actually stated in the question.

Can a Java class extend String?

The knee-jerk response here is of course not, no Java class can extend String.

The only way would be to go in the Java Development Kit (JDK) source, delete “final” from the declaration of java.lang.String, recompile the JDK, and then, using that JDK, write a class that extends java.lang.String.

As interesting as recompiling the JDK sounds to me, it’s actually overkill for this trick question. Notice that the trick question doesn’t actually specify java.lang as the package String comes from.

It is of course natural to assume that “String” refers to java.lang.String, since that class is almost always imported to other packages. But “almost always” is not the same as “always.”

Nothing forbids us from naming a class the same as a class (including enumerated types) or interface in the java.lang package. Of course that’ll cause us the inconvenience of having to fully qualify references to java.lang items. For example:

package fake.java.lang;

public class String {

@Override
public java.lang.String toString() {
return this.getClass().getName() + '@'
+ Integer.toString(this.hashCode(), 12);
}

}

Since this example String class is not marked final and the default constructor supplied by the compiler is public, we can extend this String class.

package fake.java.lang;

public class ExtendedString extends String {

@Override
public java.lang.String toString() {
return this.getClass().getName() + '@'
+ Integer.toString(this.hashCode(), 20);
}

}

The access levels of the constructors matter here. A class can be effectively final without being explicitly marked final if it only has class private constructors and no nested classes.

Of course that’s not an option for java.lang.String, which has more than a dozen public constructors, even though we rarely ever need to write an explicit constructor call for any of them.

The correct answer to the trick question is then

Yes, a Java class can extend String, provided it’s not final like java.lang.String and it has at least one accessible constructor.

There are legitimate reasons to extend java.lang.String. But that’s not what this trick question is about.

This trick question is about not jumping to assumptions, like the assumption that an unqualified use of a name matching a class or interface in java.lang must always be a reference to that class or interface.

--

--

Alonso Del Arte
Alonso Del Arte

Written by Alonso Del Arte

is a Java and Scala developer from Detroit, Michigan. AWS Cloud Practitioner Foundational certified

No responses yet