0

In the Java implementation, I found

 transient Entry[] table; 
 which is initiated in constructor as
 table = new Entry[capacity];

I know and understand that creating generic array is not allowed but then what I fail to understand is that how the whole thing works. I mean when we do something like

HashMap<Integer, String> hMap = new HashMap<Integer, String>();

How does above codes leads to creating an Entry array of type <Integer, String>

Well, few people are not able to understand what I am asking. To rephrase what I am asking is what is the point in doing something like

HashMap<Integer, String> hMap = new HashMap<Integer, String>();

When it does not result in

Entry<Integer, String>
4
  • 1
    It is unclear what you are asking. You seem to have worked out exactly what happens, it uses an array of Entry raw types. As a side note, this isn't native code, it's simply JDK code. Commented Jan 24, 2015 at 11:59
  • Thanks, I will correct 'native' part. What I am trying to ask is .. How does this <Integer, String> parameter is passed on to Entry class to ensure Entry<Integer,String> Commented Jan 24, 2015 at 12:01
  • @Walt regarding your last edit: because new Entry<K, V>[capacity] (or new Entry<Integer, String>[capacity]) is invalid Java code. It doesn't compile. You may not create arrays of generic types. Commented Jan 24, 2015 at 12:49
  • See docs.oracle.com/javase/tutorial/java/generics/… Commented Jan 24, 2015 at 12:55

3 Answers 3

7

Generics are a compile-time safety. At runtime, the map only know about Objects. This is known as type erasure. To scare you even more, the following code will run without problem:

Map<Integer, Integer> safeMap = new HashMap<>();
Map unsafeMap = safeMap;
unsafeMap.put("hello", "world");

You'll get a warning at compile time, because you're using a raw Map instead of a generic one, but at runtime, no check is done at all, because the map is a good old map able of storing any object. Only the compiler prevents you from adding Strings in a map or integers.

Sign up to request clarification or add additional context in comments.

Comments

3

The implementation makes an array of Entry<K,V> objects of type

static class Entry<K,V> implements Map.Entry<K,V>

without providing generic type parameters (source). This is allowed, but it comes with understanding that the compiler is no longer guarantees type safety. For example, in other places in code you could write

Entry<K,V> e = table[bucketIndex];

and the compiler will let you do that. If you know for sure that you always set elements of table[] to null or Entry<K,V>, then you know that the assignment is correct.

The reason this works without a problem is that generic types in Java are implemented through type erasure, i.e. there is no difference at runtime between Entry<K,V> objects Entry<Integer,Integer> and Entry<String,Long>.

1 Comment

This answer is correct. The downvoter should also downvote mine if he/she doesn't agree, but he/she should explain why.
2

Try to think of Java Generics this way: type parameters only apply to the static type of reference-typed expressions and do not apply to the type of actual instances being referred to by the reference values at runtime.

I find the above key to developing the proper intuitions when reading Java code. So the next time you see

new HashMap<Integer, String>()

read it as follows: "This is an instance creation expression of the type HashMap<Integer, String>. At runtime this expression will yield a reference to an instance of the HashMap class." As long as the compiler can precisely track what you do with the result of that expression, it can maintain the knowledge that this is indeed a HashMap<Integer, String>, but no further than that.

Now, since the static type system is not powerful enough to track the type parameters on the component type of arrays (the fact that Java's array types are covariant plays strongly here), the code is forced to break out of the static type safety network. The key observation is that on its own, this does not make the code incorrect, it only constrains the power of the compiler to find programming mistakes. This is why Java allows you to make unchecked casts from raw into generic types, although not without a warning which marks the spot where you have left the provinces of static type safety.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.