1

is it possible check the primitive type of a numeric value in Java 11?

Let's say I have a method

@Test
public void test1(){
 short x = 10;
 short y = 3;
 var z = x * y // z is of int type
}

@Test
public void test1(){
 short x = 10;
 short y = 3;
 var z = (short)x * y // z is of int type as variables are promoted
}

@Test
public void test3(){
 short x = 10;
 short y = 3;
 var z = (short)x * (short)y // is z of primitive type short? Is there 
                             // any way to check the type if it is short, long, int... 
                             // I.e z instanceof ... or something similar specifically for 
                             // primitive types?
}
miroana
  • 494
  • 3
  • 22
  • If you are using IntelliJ, put the cursor on `var`, then right click -> show context actions -> replace var with explicit type. – Sweeper Jul 30 '21 at 09:50
  • Thank you for your comment. But I won't be able to package Intellij as a depended artifact on my project. Is there any programmatic way? – miroana Jul 30 '21 at 09:54
  • Oh you want to check it at _runtime_? You shouldn't need to. Why do you want to do that? The type of every primitive is decided, set in stone, at compile time already. So if it is `int` at compile time, it will be always be `int`. – Sweeper Jul 30 '21 at 09:56
  • I was wondering if there is such a possibility as it might plausibly be handy when you try reading user inputs from a command line. – miroana Jul 30 '21 at 09:58
  • 5
    So this is an [XY problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). If you are using `Scanner` to read inputs, you _know_ the type of input you are reading, so no checking the type will not be handy. If you are using something that gives you user input as an `Object`, then checking the type could be useful, but then you would use `getClass` or `instanceof` to do that. – Sweeper Jul 30 '21 at 10:03

3 Answers3

6

There isn't a direct way to test the type of a variable or a primitive value in Java. However you can do it indirectly by exploiting method overload resolution.

Write yourself some overloaded methods like this:

public String typeOf(short arg) { return "short"; }
public String typeOf(int arg) { return "int"; }
public String typeOf(long arg) { return "long"; }

Then use them like this:

public void test1(){
    short x = 10;
    short y = 3;
    var z = x * y;
    System.out.println(typeOf(z));  // in this case "int" will be printed.
}

and so on.


However this is unnecessary. The JLS specifies what the type of z will be in each case. The answer will be int in each of those cases.

The operands of a * will be promoted to int or long, and the result will be int or long. In your second and third examples, the cast to short makes no difference1.

The only way that you will get z to be short is to do the cast after the multiplication; i.e.

z = (short)(x * y);

1 - In these cases. It would make a difference if the casts caused truncation of the significant bits; e.g. if x or y were int etcetera.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • 2
    Haha, using overloaded methods to check types. Very creative! – Sweeper Jul 30 '21 at 09:59
  • I think that this answer is very valuable. While you are entirely correct that the behaviour is fully specified by the JLS, it can be still confusing for people who are studying nuances of Java (it is often far from obvious). And this trick provides a way for self-checking your understanding. Of course, such code should never be used for anything serious or work-related :) – Rauni Lillemets Aug 10 '23 at 08:19
3

There's no way to check that at runtime, because the type is fixed at compile time. Even though you defined your variables using var: the type is still fixed at compile time (and depends on the type of the expression used to initialize it).

In all three of your examples z is of type int, because a multiplication of two any numbers of type byte, char or int will always result in an int result and you only ever cast the inputs, but never the outputs.

If you wanted var z to be of type short, then you'd need to cast the result of the calculation like this:

var z = (short) (x*y);

But if the type of z is actually important, then I'd avoid var and explicitly state the type anyway:

short z = (short) (x*y);
Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
  • A side question: What means "var" in Java? – Reporter Jul 30 '21 at 09:56
  • 1
    @Reporter: [`var` is used for type inference for the variable type](https://stackoverflow.com/questions/49636993/what-is-var-in-java-10-and-is-comparable-to-javascript). I.e. the compiler will decide the type of the variable to avoid some typing/redundancy. It's been introduced in Java 10, so if your IDE doesn't accept it, then your project is probably configured to use a language level lower than Java 10. – Joachim Sauer Jul 30 '21 at 09:59
  • Thanks for explaination, yes I have to work with Java 8. – Reporter Jul 30 '21 at 10:00
1

You can use method overloading which lets you call the same function name and run custom to the data type or number of parameters in the method.

class Type{
    String getType(short val){
        return "short";
    }
    String getType(int val){
        return "int";
    }
    String getType(long val){
        return "long";
    }
{