[Java] Reference types in Java

This article is for learning reference only!

Java is a typed language, which essentially means that every variable declared has a specific type associated with it. This type determines the values ​​it can store. For example, integer types can store non-decimal numbers. Also known as data types , this can be roughly divided into two categories: primitives and references . Primitive types are the most common, and they form the basis of type declarations, and reference types are those that are not primitive types. These reference types will be covered in detail later in this article; but first, a slight detour.

What are static and dynamic typing in Java?

A language is said to be statically typed if the type of the declared variable is known before the code is compiled . For some languages, this usually means that the programmer needs to specify the type of the variable in the code before using it (eg - Java, C, C++). Others provide a form of type inference that is able to infer the type of a variable (eg – Kotlin, Scala, Haskell). The advantage of explicit type declarations is that trivial errors can be quickly caught at an early stage.

Dynamic typing , on the other hand, means that programmers don't need to declare variables of any type, just start using them. The type is determined dynamically based on the value it stores. This is a faster way of coding because variables can store values ​​of different types - eg, numbers and strings - without having to bother with their type declarations (eg - Perl, Ruby, Python, PHP, JavaScript). Type is decided on the go. Most scripting languages ​​have this feature, mainly because there is no compiler to perform static type checking in any case. However, this makes finding bugs a bit difficult, especially if it's a large program, although scripts of this type usually have smaller code, so there are fewer places for bugs to hide.

Some languages ​​(like Rogue) take both approaches (static and dynamic). Interestingly, Java 10 introduced the var keyword. A variable declared as var automatically detects its type based on the value it stores. Note, however, that once a value is assigned, the compiler specifies its type during compilation. Later, they cannot be reused with another type in the line of code. Here is an example of how to use the var keyword in Java :

var iVar = 12;
var dVar = 4.678;
var cVar = 'A';
var sVar = "Java";
var bVar = true;

What is the difference between primitive types and reference types in Java?

In Java, since all non-primitive types are reference types, a class that specifies an object as an instance of the class is also considered a reference type. For comparison, here are the typical characteristics of primitive types relative to reference types:

  • It can store values ​​of its declared type.
  • When another value is assigned, its initial value is replaced.
  • For all primitive types, there are specific limits on their memory footprint.
  • By default they are initialized ( number with value 0 , boolean with false value)
  • They can be explicitly initialized during declaration (* int tot=10;* )
  • Declared local primitive type variables are never initialized, so trying to use them before initialization is not allowed in Java.

Some characteristics of reference types are as follows:

  • All other variables except primitives are reference types .
  • Reference types store a reference or location of an object in computer memory. Such variables refer to objects in the program.
  • Objects, or concrete instances, of a class are created using the new keyword following a constructor call. A constructor is a special member function of a class that is used to create an object by initializing all variables declared in the class with their respective default values ​​or values ​​received as constructor arguments.
  • A class instance is created by calling a class constructor, and there can be more than one.
  • Although an interface reference cannot be instantiated, an instance of a class extending an interface can be assigned to a reference of an interface type.

Java Reference Types Tutorial

Addresses of variables and reference types in Java

Unlike C/C++, where we can scrutinize memory addresses and references to variables through pointers , Java is completely silent here. There is no element in the Java language that takes the address of a variable. That's why there are no address or similar operators in the language constructs ; the language was designed from the ground up to work without it. This completely closes the door to pointers in Java.

However, if we're so keen to get close to memory - or rather, to the abstraction of memory in Java - use reference types . Reference types are not actually memory addresses, but can be tightly converted to memory addresses. Regardless, they have a similar vibe to pointers and can be treated like any other variable.

Interface Reference in Java

In Java, interfaces cannot be instantiated. Therefore, it cannot be referenced directly. However, an object of a class type that extends an interface can be used to assign a reference of that interface type. In the example below, Professor not only derives from the Person class, but also from two interfaces: Teacher and Researcher .

Therefore, according to the statement, the following hierarchy is valid:

Java reference type code example

Therefore, the following Java code example compiles fine:

public class Main{
    
    
    public static void main(String[] args){
    
    
        Professor professor = new Professor("112233", "Donald Ervin Knuth", Date.valueOf(LocalDate.of(1938,1,10)), 9.8f);
        Person person = new Professor("223344", "Dennis Ritchie", Date.valueOf(LocalDate.of(1941,9,9)),9.7f);
        Teacher teacher = new Professor("223344", "Andrew S Tanenbaum", Date.valueOf(LocalDate.of(1944,3,16)),9.6f);
        Researcher researcher = new Professor("223344", "Ken Thompson", Date.valueOf(LocalDate.of(1943,2,4)),9.5f);
    }
}

Here, four objects of type Professor are assigned to different reference types, which also include two interface reference types. Assume the stack and heap contents of a reference type are as follows:

Java code example

The following references are also available:

Professor professor = new Professor("112233", "Donald Ervin Knuth", Date.valueOf(LocalDate.of(1938,1,10)), 9.8f);

Person person = professor;
Teacher teacher = professor;
Researcher researcher = professor;

In this case, the stack and heap memory will look like this, where an object has multiple references:

Java stack and heap memory

Note, however, that the reference must be a supertype of the assigned object . This means that the following assignments are invalid (and won't compile):

person = professor; //valid
professor = person; //invalid

The reason for this is that references are used to call public methods declared in the class. Therefore, the object the reference points to must have access to these methods. Here, the reference professor does not have access to one's property. As a result, the Java compiler complains about the allocation. Some smart code editors and IDEs are also able to identify invalidities and flag messages and warn programmers before compilation.

However, an explicit cast can be used to convince the compiler that everything is ok:

professor = (Professor)person; //valid

END

By default, reference type instances are initialized to the value null . null is a reserved keyword in Java, which means that reference types point to anything in memory. One aspect of not having pointers in Java is that, in most cases, reference types can be treated almost like any other variable. Pointers have an odd look, and many programmers don't like it for this reason (but some still like it). Put down the programmer's hand, there is still a reference to the object in memory - you get the Java reference type.

Guess you like

Origin blog.csdn.net/m0_47015897/article/details/131417060