Why are Wrapper Classes, String,... final ? - java

Many classes in the Core Java API are final (Wrapper classes, String, Math).
Why is it so ?

They are final for security reasons. There may be other reasons, but security is the most important.
Imagine an ability to inherit java.lang.String, and supply your own, mutable implementation to a security-sensitive API. The API would have no choice but take your string (remember the substitution principle) then but you would be able to change the string from under them (on a concurrent thread or after the API has returned), even after they have checked it to be valid.
Same goes for wrappers of primitives: you do not want to see them mutable under any circumstance, because it would violate important assumptions about their behavior encoded in the APIs using these classes.
Making String final addresses this issue by not letting others supply their own, potentially hostile, implementations of classes as fundamental as String.

You might want to prevent other programmers from creating subclasses or from overriding certain methods. For these situations, you use the final keyword.
The String class is meant to be immutable - string objects can't be modified by any of their methods. Since java does not enforce this, the class designers did. Nobody can create subclasses of String.
Hope this answers your question.

Related

Documentation of immutability of Java wrapper classes

It is well-known that the type wrappers such as Integer, Double, Boolean are immutable. However, I was unable to find this documented in the official API documentation, e.g., https://docs.oracle.com/javase/8/docs/api/java/lang/Boolean.html. I also looked in the source code files, and did not find this stated in the comments. (The comments in the source code for String, on the other hand, does mention its immutability.)
Is this because:
- it's documented elsewhere (if so, where?),
- this fact is too "well-known", or
- the developer is expected to read the implementation of the wrappers and figure out whether the wrapper is immutable or not?
It is worth consideration that immutable can mean two things:
a) that if you pass this value somwhere it can't be mutated.
b) "a" and that it can be safely used in multithreaded environment
ad A) There are classes that are just immutable but not thread safe, they are good to be used with setters/getters and to be keys in HashMap - these ones with no mutators, with all fields private but without all fields final or volatile.
ad B) There are classes that are immutable and thread safe - these without mutators and with all fields private and final or volatile.
Classes that are thread safe are often described as so in the documentation or even by name, of course some classes can be immutable and/or thread safe but not strictly documented as so. For example the String class is documented to be "constant", but there is no information about thread safety - there is only one enigmatic statement "Because String objects are immutable they can be shared" but I think it means something different than ...shared with other threads. We just know the properties of popular classes, but I agree that these properties should be clearly documented. Unfortunatelly in real life they aren't. So the only way to know if class is immutable is to check the documentation and if there is not enough information, then check the implemetation and ask the author if He plans to make the class mutable in the future. This topic is considered in a book Java Concurrency in Practice, and the author suggest to use two annotations to denote that something is #ThreadSafe and/or #Immutable but unfortunatelly this isn't a common practice yet.
The boxed wrappers are "immutable" because they're virtually
interchangeable syntactically with the literal types they wrap. For example boolean is immutable:
boolean x = false;
x.flip(); // not implemented
Native types in most programming languages are immutable. Therefore, by the wrapper contract,
Boolean x = false;
x.mutate(/* ??? */);
is not defined either.

Why is javaslang CharSeq final?

We're all familiar with the argument about why String is final in java.
However, I was wondering why javaslang's CharSeq is final too.
Given javaslang's FP inspirations and the fact that Haskell allows type synonyms, I would have thought this would be a good opportunity to make CharSeq non-final with maybe the methods as final.
A non-final CharSeq would then allow me to extend it with an empty body to create a good approximation of type synonyms. This would avoid the boilerplate of the tiny type pattern for cases where the additional type safety is desired.
I'm sure there is a good reason why this is not the design, which is why I am asking here.
UPDATED 16-Dec-2016: I've raised an enhancement request with the javaslang team on github as issue #1764.
All the same reasons for and against apply.
Java's designers believed that guaranteeing immutability was worth losing the ability to subclass.
Slang's designers agree, and took the same approach with their "String", CharSeq.
The only internally consistent way to disagree with this design, would be to also disagree with String's design, which has stood the test of time.
Sometimes we wish we could subclass String, and we can't - but it doesn't sting us often. If you really want to, you could write your own String that proxies all methods to a java.lang.String delegate. You could subclass that as much as you like. It would be your own responsibility not to introduce mutability.

Comparing C#'s attributes and Java's marker interfaces

Yesterday I came across attributes in C#, the [Serializable] to be precise. As I understand it, they are used like metadata, to provide some information about your class.
Also, I learned that Java has "marker interfaces", the ones with no methods, that serve the purpose of explaining the class, i.e. marking some characteristic of the class, for example the Serializable interface.
I was wondering: can you make a parallel between the two? Are they similar, or even the same?
C# attributes are more like Java annotations. (I believe that's where Java got the idea.)
Marker interfaces are a Java 1.0 construct that are rarely used in new code, if ever. I don't find them to be useful. I would not recommend reviving the practice.
Java interfaces should be for separating declaration of method signatures ("what") from implementation ("how"). They should be like C++ pure virtual classes, not attributes or annotations.
several years ago , Java didn't support attributes. Therefore, to "tag" a class or an interface so that
they could be checked at runtime, you would use marker interfaces,
which is basically an empty interface but you can still check if an instance can be casted to this interface.
In .NET, marker interfaces should not be used except for special use cases (such as allowing the use of extension methods),
because attributes provide a better way to mark classes (and lots more) with metainformation. The same goes for Java 5 and newer,
where annotations were introduced and should be used instead.
Marker interfaces:
1) are a bit easier to check for using dynamic type checks (´obj is IMarker´);
2) allowed for functional and data extensibility in the future (i.e. turning a “marker” interface into a “full” interface that actually declares some members);
3) can be used in generic type constraints;
Attributes:
provide a clearer separation of metadata;
allow for specifying additional information via their constructors or properties;
allow for multiple application to an entity;
are general-purpose in terms of applicability to different kinds of entities, not just classes;
It heavily depends on the particular application's architecture and design whether it's appropriate to use a marker interface or an attribute in a particular case.

Immutability and General vs. Specific Types

This is in the context of creating an interface/API.
Best practices suggest using general rather than specific types in interfaces - e.g. Map rather than HashMap.
Best practices also suggest preferring immutable types over mutable ones.
So considering both of these suggestions (and leaving aside concerns about performance/memory-footprint, 3rd-party-libraries/dependencies and convenience/functionality) should a method in a public interface look like this
public List<SomeClass> someMethod(...)
or rather this
public ImmutableList<SomeClass> someMethod(...)
When this has been discussed among the Guava folks, the following has been said:
The basic advice for types exchanged by APIs is this: choose the most general type that still conveys the relevant semantic information.
I consider the trio of semantic guarantees made by ImmutableCollection to be extremely relevant for return values in almost any circumstance (those three being immutability, lack of null elements and guaranteed iteration order). So I would virtually always return ImmutableSet, not Set.
We would really like people to view ImmutableSet etc. as being interfaces in every important sense of the word. There are only two reasons they are not: reliability of the immutability guarantee, and the fact that Java won't allow static methods on interfaces until JDK 8, and we wanted them there for convenience.
Most people think ImmutableList is an implementation for this reason, but there are actually several to dozens of different implementations of some of these types; you just don't see them.
If the method's contract guarantees that the List is immutable then the return type should be the ImmutableList rather than the List. This is much more explicit than simply mentioning that the List is immutable in the method's JavaDoc.
However, if the immutability of the list is an implementation detail, rather than a contract then the return type should be the List.
Writing APIs is about having contract with the users.
Best practices are mostly for the context where you need to write APIs for third parties and need to define the interfaces.
We can have different view in different contexts. If you are writing library which is going to be used by third party, you need to consider that they should or should not change the object state.
If API is going to be consumed internally (with in same code base) & purpose is to achieve loose coupling then you need to think about ease of writing, extensibility and maintainability.
Immutable APIs would avoid the data inconsistency specially when you made lot of assumptions on state of the object. On the other hand, mutable object would allow to save development efforts.

When is a reference to the object class required?

What is the function of the class Object in java? All the "objects" of any user defined class have the same function as the aforementioned class .So why did the creators of java create this class?
In which situations should one use the class 'Object'?
Since all classes in Java are obligated to derive (directly or indirectly) from Object, it allows for a default implementation for a number of behaviours that are needed or useful for all objects (e.g. conversion to a string, or a hash generation function).
Furthermore, having all objects in the system with a common lineage allows one to work with objects in a general sense. This is very useful for developing all sorts of general applications and utilities. For example, you can build a general purpose cache utility that works with any possible object, without requiring users to implement a special interface.
Pretty much the only time that Object is used raw is when it's used as a lock object (as in Object foo = new Object(); synchronized(foo){...}. The ability to use an object as the subject of a synchronized block is built in to Object, and there's no point to using anything more heavyweight there.
Object provides an interface with functionality that the Java language designers felt all Java objects should provide. You can use Object when you don't know the subtype of a class, and just want to treat it in a generic manner. This was especially important before the Java language had generics support.
There's an interesting post on programmers.stackexchange.com about why this choice was made for .NET, and those decisions most likely hold relevance for the Java language.
What Java implements is sometimes called a "cosmic hierarchy". It means that all classes in Java share a common root.
This has merit by itself, for use in "generic" containers. Without templates or language supported generics these would be harder to implement.
It also provides some basic behaviour that all classes automatically share, like the toString method.
Having this common super class was back in 1996 seen as a bit of a novelty and cool thing, that helped Java get popular (although there were proponents for this cosmic hierarchy as well).

Categories