User Konstantin
Konstantin
Level 36
Odesa

Exploring questions and answers from a job interview for a Java developer position. Part 4

Published in the Success Stories group
Hello, everyone! Today I'm continuing my review of Java developer interview questions. Exploring questions and answers from a job interview for a Java developer position. Part 4 - 1

29. Can return be used in a constructor?

Yes, but only without a value to the right of the return keyword. You can use return; as a helper statement in a constructor to urgently terminate (interrupt) execution of further code and finish the initialization of the object. For example, suppose we have a Cat class, and if a Cat is homeless (isHomeless = true, then we want to terminate initialization and not fill in the other fields (after all, they are unknown to us, since the cat is homeless):

public Cat(int age, String name, boolean isHomeless) {
   if (isHomeless){
       this.isHomeless = isHomeless;
       return;
   }
   this.isHomeless = isHomeless;
   this.age = age;
   this.name = name;
}
But if we're talking about concrete values, then the return keyword cannot return a specific value because:
  • when you declare a constructor, you won't have anything like the return type;
  • as a rule, the constructor is implicitly called during instantiation;
  • the constructor is not a method: it is a separate mechanism whose sole purpose is to initialize instance variables, i.e., we're using the new operator to create an object.
Exploring questions and answers from a job interview for a Java developer position. Part 4 - 2

30. Can an exception be thrown from a constructor?

Constructors work with exceptions in the same way that methods do. Methods allow us to throw exceptions by writing throws <ExceptionType> in the method header. And constructors allow us to do the same. When we are inheriting and defining the constructor of a child class, we can widen the exception type — for example, IOException -> Exception (but not vice versa). Let's use the constructor of the Cat class as an example of a constructor throwing an exception. Let's say that when we create an object, we want to enter the name and age from the console:

public Cat() throws IOException {
   BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
   this.name = reader.readLine();
   this.age = Integer.parseInt(reader.readLine());
}
Since reader.readLine() throws an IOException, we write it in the header as a possible thrown exception.

31. What are the elements of a class header? Write an example

To illustrate the elements that make up a class header, let's look at a small schema:
  • mandatory elements appear in brackets <>
  • optional elements are in {}
{access modifier}{static}{final}{abstract}<class name>{inheritance of Parent class}{implementation of interfaces} So, what we have: {access modifier} — only the public and default access modifiers are available for the class. {static} — the static modifier indicates that this class is static; it applies only to inner classes (classes inside other classes). {final} — this is the final modifier, of course, which makes the class uninheritable (an out-of-the-box example is String). {abstract} — the abstract modifier, which indicates that the class may have unimplemented methods. This modifier conflicts with the final modifier. The class header can only have one of them since the abstract modifier means that the class will be inherited and its abstract elements will be implemented. But final indicates that this is the final version of the class, and that it cannot be inherited. Actually, simultaneously using both modifiers would be absurd. The compiler will not let us do this. <class> is a mandatory keyword that indicates a class declaration. <class name> is a simple class name that becomes the identifier of a specific Java class. The fully qualified class name consists of the qualified package name plus '.' plus the simple class name. {inheritance of the Parent class} is an indication of the parent class (if any) using the extends keyword. For example, ... extends ParentClass. {implementation of interfaces} — a list of the interfaces that this class implements (if any), using the implements keyword. For example: ... implements FirstInterface, SecondInterface ... As an example, consider the class heading of the Lion class, which inherits Cat and implements the WildAnimal interface:

public final class Lion extends Cat implements WildAnimal
Exploring questions and answers from a job interview for a Java developer position. Part 4 - 3

32. What are the elements of a method header? Write an example

When considering the elements that make up a method header, let's again consider a small schema:
  • mandatory elements appear in brackets <>
  • optional elements are in {}
{access modifier}{static}{abstract}{final}{synchronized} {native} <return value><method name> <(>{method parameters}<}>{throw exceptions} {access modifier} — all access modifiers are available for the method — public, protected, default, private. {static} — the static modifier, which indicates that the method is static and therefore associated with the class, not an object. {abstract} — the abstract modifier, which indicates that the method has no implementation (body). To work correctly, the class that declares the method must also have the abstract modifier. As in the class header, this modifier conflicts with the final modifier, and also conflicts with the static modifier, because an abstract method implies overriding the method in a descendant, and static methods cannot be overridden. {finale} — the final modifier, which indicates that this method cannot be overridden. {synchronized} — the synchronized modifier, which means that the method is protected from simultaneous access to it from different threads. If the method is not static, then it is closed for the object's this mutex. If the method is static, then it is closed for the mutex of the current class. {native} — the native modifier indicates that the method is written in another programming language. <return type> — the type of the value that the method must return. If the method doesn't return anything, then void. <method name> — the name of the method name, i.e. its identifier in the system. {method parameters} — the parameters that the method accepts: they are necessary to implement its functionality. {thrown exceptions}throws <ExceptionType> — a list of the checked exceptions that this method can throw. I'll offer the following as an example of a method header:

public static void main(String[] args) throws IOException

33. Create a default constructor in a child class if one is not already defined in the base class (but a different constructor is defined)

I'm not sure I fully understand the question, but maybe it means that we have some constructor like this in the parent class:

public Cat(int age, String name) {
   this.age = age;
   this.name = name;
}
In that case, in the parent class, we definitely need to define a constructor that will initialize the parent (i.e. call the parent constructor):

public class Lion extends Cat {
 
   public Lion(int age, String name) {
       super(age, name);
   }
}
Exploring questions and answers from a job interview for a Java developer position. Part 4 - 4

34. When is the this keyword used?

In Java, this has two different meanings. 1. It is a reference to the current object, e.g. this.age = 9. That is, this refers to the object in which it is used and to which the code with this refers. The main purpose is to improve code readability and avoid ambiguity. For example, if an instance field and a method argument have the same name:

public void setName(String name) {
   this.name = name;
}
That is, this.name is the object's field, while name is the method parameter. The this reference cannot be used in static methods. 2. In the constructor, this can be called like a method, e.g. this(value). In this case, it will be a call to another constructor of the same class. Basically, you can call two constructors during the process of creating an object:

public Cat(int age, String name) {
   this(name);
   this.age = age;
}
 
public Cat(String name) {
   this.name = name;
}
When calling the first constructor to create a Cat object, both instance fields will be successfully initialized. There are a couple of nuances here:
  1. this() only works in a constructor.
  2. A reference to another constructor must be in the first line of the constructor block (body). This means that a constructor cannot call more than one (other) constructor of its class.
Exploring questions and answers from a job interview for a Java developer position. Part 4 - 5

35. What is an initializer?

As far as I understand, this question is about ordinary and static initialization blocks. Let's first remember what initialization is. Initialization is the creation, activation, preparation, and definition of fields. Preparing a program or component to be ready for use. You will recall that when you create an object, a class variable can be initialized immediately when it is declared:

class Cat {
   private int age = 9;
   private String name = "Tom";
Or set after the fact through the constructor:

class Cat {
   private int age;
   private String name;
 
   public Cat(int age, String name) {
       this.age = age;
       this.name = name;
   }
But there is another way: you can set an instance variable using an initialization block, which takes the form of curly braces {} inside a class, without a name (like a nameless method or constructor):

class Cat {
   private int age;
   private String name;
 
   {
       age = 10;
       name = "Tom";
   }
An initialization block is a piece of code that is loaded when an object is created. Such blocks are typically used to perform certain complex calculations that are required when a class is loaded. The results of these calculations can be set as the values of variables. In addition to ordinary initialization blocks, there are static ones. They look the same but have the static keyword in front of the opening curly brace:

class Cat {
   private static int age;
   private static String name;
 
   static{
       age = 10;
       name = "Tom";
   }
This block is the same as the previous one. But if the ordinary one is executed when each object is initialized, then the static one is executed only once, when the class is loaded. As a rule, certain complex calculations are performed in a static block, used to initialize static class variables. The same restrictions apply to a static block that applies to static methods: you cannot use non-static data, such as a reference to the current object (this) in a static block. Exploring questions and answers from a job interview for a Java developer position. Part 4 - 6Now we can look at the order of the initialization of the class (together with its parent class) in order to better understanding when exactly the initialization blocks are invoked.

36. Given a public Child class that extends Parent, write out the initialization order of the object

When loading the Child class, the initialization order will be as follows:
  1. Static class fields of the Parent class.
  2. Static initialization block of the Parent class.
  3. Static fields of the Сhild class.
  4. Static initialization block of the Child class.
  5. Non-static fields of the Parent class.
  6. Non-static initialization block of the Parent class.
  7. Parent class constructor.
  8. Non-static fields of the Сhild class.
  9. Non-static initialization block of the Сhild class.
  10. The constructor of the Сhild class.
Exploring questions and answers from a job interview for a Java developer position. Part 4 - 7

37. What sort of relationships between classes (objects) do you know?

There are two kinds of variables in Java: primitive types and references to full-fledged objects.
  • IS-A relationships
OOP's IS-A principle is based on class inheritance or implementation of interfaces. For example, if the Lion class inherits Cat, then we say that Lion is a Cat:

Lion IS-A Cat
(but not every Cat is a Lion) The same situation exists with interfaces. If the Lion class implements the WildAnimal interface, then they also exist in the relationship:

Lion IS-A WildAnimal
  • HAS-A relationship
This type of relationship is where one class uses other classes, also called "association". An association is one class that refers to another class (or mutual references to each other). For example, the Car class can reference the Passenger class, which would constitute the following relationship:

Car HAS-A Passenger
And vice versa: if Passenger has a reference to Car, then this will be the relationship:

Passenger HAS-A Car

38. What associative object relationships do you know?

Aggregation and composition are nothing more than special cases of association. Aggregation is a relationship where one object is part of another. For example, a passenger might be located in a car. What's more, there may be multiple passengers or none at all (and if we're talking about Tesla, there may be no driver). For example:

public class Car {
   private List passengers = new ArrayList<>();
 
 void setPassenger(Passenger passenger) {
     passengers.add(passenger);
 }
 
   void move() {
       for (Passenger passenger : passengers) {
           System.out.println("Transporting passenger - " + passenger.toString());
       }
       passengers.clear();
   }
}
In other words, the number of passengers (in any) is not important to us: the Car class's functionality does not depend on this. Aggregation also implies that when another object uses one object, the first object can be used by other objects. For example, the same student may be in both a knitting club and a rock band and simultaneously attend a Spanish class. As you can imagine, aggregation is a looser associative relationship between classes. Composition is an even tighter relationship where an object is not only part of another object, but one object's work is very dependent on another. For example, a car has an engine. An engine may exist without a car, but it is useless outside of a car. And a car cannot work without an engine:

public class Car {
   private Engine engine;
 
   public Car(Engine engine) {
       this.engine = engine;
   }
 
   void startMoving() {
       engine.start();
           ...
   }
Composition also implies that when another object uses an object, the first object cannot belong to any other object. Going back to our example, an engine can only belong to one car, not two or more at the same time. I think that is enough for today, so we'll stop here.
Read more:
Exploring questions and answers from a job interview for a Java developer position. Part 4 - 8
Comments (1)
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION
Abha Sharma Level 1, India
4 September 2021
Thank you for sharing , very informative