Q:

why java supports function overloading for primitive data types?

while going through Autoboxing and unboxing in java, i learned that java converts primitive data types to Wrapper Class and vice versa whenever needed. e.g. if function is taking Integer as parameter if we pass value as 1 then java compiler will convert it to new Integer(1). now below is my case. 
public class JavaTest 
{

    public static void Test(Integer integer)
    {
        System.out.println("in Integer");
    }

    public static void Test(int integer)
    {
        System.out.println("in int");
    }

    public static void main(String[] args) 
    {
        Test(1);
    }
}

in this case java should have thrown compile time exception. but it compiles successfully and prints below result 

in int

if i removes the Test(int integer) method then java gives me result

in integer

so my question is why java is allowing such function overloading ?

A:

Java allows such overloading for backwards compatibility.
Since auto-boxing and auto-unboxing was introduced in Java 5.0, the first stage of method overload resolution attempts to find a matching method without using auto-boxing and auto-unboxing. 
Therefore, only the method that takes an int argument is found in your example. When you remove that method, no match is found in the first stage of method overload resolution, and the second stage uses auto-boxing in order to match the method that takes an Integer argument.

15.12.2. Compile-Time Step 2: Determine Method Signature
The remainder of the process is split into three phases, to ensure compatibility with versions of the Java programming language prior to Java SE 5.0. The phases are:

The first phase (§15.12.2.2) performs overload resolution without permitting boxing or unboxing conversion, or the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the second phase.
This guarantees that any calls that were valid in the Java programming language before Java SE 5.0 are not considered ambiguous as the result of the introduction of variable arity methods, implicit boxing and/or unboxing. However, the declaration of a variable arity method (§8.4.1) can change the method chosen for a given method method invocation expression, because a variable arity method is treated as a fixed arity method in the first phase. For example, declaring m(Object...) in a class which already declares m(Object) causes m(Object) to no longer be chosen for some invocation expressions (such as m(null)), as m(Object[]) is more specific.
The second phase (§15.12.2.3) performs overload resolution while allowing boxing and unboxing, but still precludes the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the third phase.
This ensures that a method is never chosen through variable arity method invocation if it is applicable through fixed arity method invocation.
The third phase (§15.12.2.4) allows overloading to be combined with variable arity methods, boxing, and unboxing.

