Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are Java primitive types' modifiers public, abstract, and final?

Tags:

In the process of doing some reflection on Java types, I came across an oddity that I do not understand.

Inspecting int for its modifiers returns public, abstract, and final. I understand public and final, but the presence of abstract on a primitive type is non-obvious to me. Why is this the case?

Edit: I am not reflecting on Integer but on int:

import java.lang.reflect.Modifier;  public class IntegerReflection {     public static void main(final String[] args) {         System.out.println(String.format("int.class == Integer.class -> %b", int.class == Integer.class));         System.out.println(String.format("int.class modifiers: %s", Modifier.toString(int.class.getModifiers())));         System.out.println(String.format("Integer.class modifiers: %s", Modifier.toString(Integer.class.getModifiers())));     } } 

The output when run:

int.class == Integer.class -> false int.class modifiers: public abstract final Integer.class modifiers: public final 
like image 712
oconnor0 Avatar asked Nov 01 '12 15:11

oconnor0


People also ask

Why does Java have primitive types?

The main reason primitive data type are there because, creating object, allocating heap is too costly and there is a performance penalty for it. As you may know primitive data types like int, float etc are most used, so making them as Objects would have been huge performance hit.

What is the purpose of primitive data types?

Primitive types are the most basic data types available within the Java language. There are 8: boolean , byte , char , short , int , long , float and double . These types serve as the building blocks of data manipulation in Java. Such types serve only one purpose — containing pure, simple values of a kind.

Why are primitives not possible as generic types?

Using generics, primitive types can not be passed as type parameters. In the example given below, if we pass int primitive type to box class, then compiler will complain. To mitigate the same, we need to pass the Integer object instead of int primitive type.

What is abstract static and final in Java?

Java provides a number of non-access modifiers to achieve many other functionalities. The static modifier for creating class methods and variables. The final modifier for finalizing the implementations of classes, methods, and variables. The abstract modifier for creating abstract classes and methods.


1 Answers

According to the JLS 8.1.1.1 - Abstract Classes:

An abstract class is a class that is incomplete, or to be considered incomplete.

By definition, there can be no instances of int.class. You can't compile this kind of code:

int a = new int(); 

There are no constructors for int. There are no objects created. int.class does not even extend Object. If you run the following line of code, you will get null as the result.

System.out.println(int.class.getSuperclass()); 

So because you can never have a true instance of the int.class, it is by definition abstract. Also, according to the Integer API, the Integer.TYPE field (which holds int.class) is a class which only represents the primitive type.

This is proven by the following code:

int a = 4; System.out.println(int.class.isInstance(a)); 

This returns false.

As such, int.class is likely just used in the system for representation purposes, as said in the Integer API. The fact that there is also a void.class type but no null.class type makes me think that this is used primarily with Reflection. This is just conjecture, though.


If anyone is interested, the int.class essentially contains nothing that the reflection package recognizes and is likely just a dummy class. If you run the following code, you will see that it has no constructors, no fields, and no methods.

Method[] intMethods = int.class.getMethods();  if(intMethods.length == 0) {     System.out.println("No methods."); } else {     for(Method method : intMethods) {         System.out.println(method.getName());     } }  Constructor[] intConstructors = int.class.getConstructors();  if(intConstructors.length == 0) {     System.out.println("No constructors."); } else {     for(Constructor constructor: intConstructors) {         System.out.println(constructor.getName());     } }  Field[] intFields = int.class.getFields();  if(intFields.length == 0) {     System.out.println("No fields."); } else {     for(Field field: intFields) {         System.out.println(field.getName());     } } 
like image 185
asteri Avatar answered Sep 29 '22 08:09

asteri