6

I have an interesting question which entails the use of Hashtables; I'm developing for S40 Nokia's (with compliance level 1.4)

How I expect the Hashtable to work:

Hashtable table = new Hashtable();
table.put(1, "Hello World");

However I get the error:

The method put(Object, Object) in the type Hashtable is not applicable for the arguments (int, String)

However when I create an object reference and pass the reference, it works fine! Why?!

Working example:

Hashtable table = new Hashtable();
Integer test = new Integer(1);
table.put(test, "Hello World");

Any explanations would be great!

Vulcronos
  • 3,428
  • 3
  • 16
  • 24
dan983
  • 454
  • 2
  • 5
  • 19
  • 3
    Your code works fine on my end. Are you sure their isn't another underlining problem ? are you sure your Hashtable is of type import java.util.Hashtable; – Arno_Geismar Jul 14 '14 at 11:06
  • @Arno_Geismar Using which JDK ?? – Suresh Atta Jul 14 '14 at 11:06
  • As far as you are developing for Nokia S40 I understand that this is J2ME. Is is a chance that you build your app using some additional tools, i.g. obfuscator, J2MEPolish etc? – AlexR Jul 14 '14 at 11:12
  • I'm wondering... what happens if you do table.put(((Integer) new Integer(1)),"Hello World"); ? – luanjot Jul 14 '14 at 11:14
  • Or you may try `table.put((object)1,"Hello, World");` – Earth Engine Jul 14 '14 at 11:21
  • Autoboxing not available in Java 1.4, It was introduced in 1.5. That might be a problem. – naveejr Jul 14 '14 at 11:22
  • In the first case you lost the reference to the newly created Integer just after you put it in the table. There is no way to retrieve the object. But in the second case you maintain a reference outside, which can be used later to retrieve it. – naveejr Jul 14 '14 at 11:26
  • 1
    @dan983 - are you sure you posted here the actual code which causes the errror? I believe what you actually *have* there is `table.put(1, "Hello World");` *This* really causes the error you have described. I checked it under 1.4 and it behaves exactly as you described, but not with the code you provided. – Honza Zidek Jul 14 '14 at 11:26
  • I'm migrating android software over to Nokia however it seems that Nokia is a bit more limited, HashTable is using that import @Arno_Geismar. – dan983 Jul 14 '14 at 11:50
  • I do use the obfuscator (only when packaging the jad/jar files) . I tried casting it had the same failure . @Honza Zidek , the code does cause the error, I can't even declare generic types as it forces me to use compliance 1.5 ! – dan983 Jul 14 '14 at 11:54
  • [Solved] Ok, so after changing compiler compliance level to 1.5 then back to 1.4 seemed to fix the issue!, I did compile with table.put(1, "Hello World"); initially and changed my code to what I have posted here and cleaned my project however it must have confused, thanks for all the replies folks! I would upvote @HonzaZidek but you never left a full answer! – dan983 Jul 14 '14 at 12:01
  • @dan983 - my full answer see below, with detailed explanation. Please fix your question so it is clear to other people, otherwise your question causes confusion. – Honza Zidek Jul 14 '14 at 12:05

6 Answers6

4

In my answer I suppose that your actual code was in fact the following:

Hashtable table = new Hashtable();
table.put(1, "Hello World");

That's the code which causes the error you have described, i.e.

The method put(Object, Object) in the type Hashtable is not applicable for the arguments (int, String)

The reason is this:

  1. Java 1.4 does not support generics, so the Hashtable simply works with Objects (both as keys as well as values)

  2. Java 1.4 does not support autoboxing, so the code table.put(1, "Hello World") is not automatically autoboxed to table.put(Integer.valueOf(1), "Hello World"). Hence you are trying to call table.put(int, String) which is not compatible with Hashtable.put(Object, Object).

Voila.

If you used Java 1.5+, the call would be autoboxed to table.put(Integer, String)

BTW, do not use new Integer(1), always prefer the static factory method Integer.valueOf(1). You may avoid unnecessary creation of redundant classes. This is what the autoboxing is compiled into. See this: Static factory methods vs Instance (normal) constructors?

Community
  • 1
  • 1
Honza Zidek
  • 9,204
  • 4
  • 72
  • 118
  • I changed the compliance level to 1.5 then back to 1.4 and it seems to compile fine now with .put(new Integer(1),"Hello World"). Cool thanks for the suggestion! – dan983 Jul 14 '14 at 12:09
  • For Java ME I need to use Integer.valueOf("1") – dan983 Jul 14 '14 at 12:20
  • `Integer.valueOf(String)` is not a good alternative to `new Integer(int)`. The conversion from `String` is even more expensive. If you don't have the `Integer.valueOf(int)` method, just use `new Integer(int)`. – Honza Zidek Jul 24 '14 at 14:11
3

From the error message you mentioned,

The method put(Object, Object) in the type Hashtable is not applicable for the arguments (int, String)

It is clear that your compiler treats the Integer object as a primitive value just after it is initialized. Namely it applies unboxing immediately. This might have been done for optimiziation in mobile platforms, if I can find a reference for it, I'll update my answer.

Juvanis
  • 25,802
  • 5
  • 69
  • 87
  • I think Autoboxing is not available in java 1.4. it was introduced in 1.5. – naveejr Jul 14 '14 at 11:24
  • 2
    I do not believe the code the OP put here is the *actual* code which caused the error. I believe what he had there was `table.put(1, "Hello World");`, or something like that. – Honza Zidek Jul 14 '14 at 11:28
  • @HonzaZidek probably that's the case. i searched for unboxing optimization for j2me but couldn't find decent results. – Juvanis Jul 14 '14 at 11:29
  • Let's wait for the OP's answer. I reckon the whole question is just a mistake. – Honza Zidek Jul 14 '14 at 11:31
2

Problem with your code is that, as you mentioned, is 1.4 compliance, which makes me think you're compiling for it to be 1.4 compatible. Boxing / unboxing is a feature added in 1.5.

Just for you to confirm what I mean: try compiling your code with javac --source 1.5 --target 1.5, it will compile fine, but try the same with javac --source 1.4 --target 1.4 then it will complain

morgano
  • 17,210
  • 10
  • 45
  • 56
0

I ignore which JVM is being used for Java develop in Nokia mobiles (I would assume a Java ME), but indeed in a typical Java SE environment your code should not give an error, but a warning: You have not used the templates to construct the HashTable, so the JVM ust assume your Integer and String are Object class, instead of the real values.

To avoid this warning, that for some reason your IDE reports as an error, use:

Hashtable<Integer, String> table = new Hashtable<Integer, String>();
table.put(new Integer(1),"Hello World");
Alex
  • 975
  • 10
  • 24
  • I don't think this is the issue. If his compiler was throwing errors due to *Generics*, the second case shouldn't work either.. – TheLostMind Jul 14 '14 at 11:11
  • Which second case?? The compiler tells the default template implementation is not applicable for . This is however accepted by the standard but there must be a previous cast from Integer and String to Object to being able to call the Hashtable constructor. – Alex Jul 14 '14 at 11:29
  • Why would the compiler tell that -*the default template implementation is not applicable for .* ?. The second case is the one where the code works. – TheLostMind Jul 14 '14 at 11:34
  • 1
    That's why I suspect he's not using a typical JVM. Probably he's using a Java ME, or a specific IDE, that shows the above message, prior to build, even when it's not an error and automatic cast to a parent object is definitely allowed. – Alex Jul 14 '14 at 11:38
0

As stated previously you probably don't have the autoboxing feature introduced in java 1.5 as you are running on compliance level 1.4. My suggestion is setting your IDEA jdk to 1.4 instead of 1.7 that you are currently using.

Arno_Geismar
  • 2,296
  • 1
  • 15
  • 29
-1

Integer is an object. int is not an object, it is a primitive. The object Integer wraps the primitive int. The put(Object, Object) method requires two objects, not a primitive and an object.

rossum
  • 15,344
  • 1
  • 24
  • 38