Review constructor restrictions, compatible references, numerical widths, and the difference between a UTF-16 code unit and a complete Unicode character.
Answer: A constructor initializes a newly created instance; it is not a class method. Java's constructor grammar does not permit static. Class-level initialization instead uses static field initializers or static initializer blocks.
A static factory method is another distinct concept: it can return a new instance or an existing one and has an ordinary method name and return type. Calling it may invoke a constructor internally, but that does not make the constructor static.
Answer: Constructors are not inherited or overridden, so the method-level purpose of final does not apply to them. Java rejects final as a constructor modifier.
Use a final class to prevent subclassing, or use constructor access to control construction. These are separate design choices. A superclass constructor still executes while initializing a subclass instance, but that call is constructor chaining, not an override.
Answer: It holds a reference value identifying an object, or null. It does not contain the object's entire state. Assigning one reference variable to another copies the reference, so both may refer to the same mutable object.
Java does not expose ordinary reference values as numeric addresses on which application code can perform pointer arithmetic. The declared reference type determines which members and operations are available at compile time, while the referenced object's class can determine the implementation of an overridden instance method.
Answer: It can hold a reference compatible with its declared type under Java's conversion rules, or null. A superclass reference can refer to a subclass instance, and an interface reference can refer to an implementing instance.
Generic compatibility matters: List<String> is not a subtype of List<Object>. Arrays have separate covariance rules and runtime store checks. A cast can change the compile-time view of a reference but cannot transform the object into an unrelated type.
Answer: The signed integral types are byte, short, int, and long, with widths of 8, 16, 32, and 64 bits. Char is also integral: it is an unsigned 16-bit value representing a UTF-16 code unit.
Char and short have equal widths but different ranges, so neither is a simple replacement for the other. Arithmetic on byte, short, and char commonly promotes values to int. These specified widths do not measure the complete memory footprint of boxed objects or arrays containing those values.
Answer: Float uses the IEEE 754 binary32 format and double uses binary64. Double therefore uses twice the value bits and has greater precision and range, but not simply twice the count of reliable decimal digits.
Float has 24 bits of significand precision and double has 53 for normal values. Decimal floating-point literals are double by default; an f suffix requests float. Both formats can represent infinities, signed zero, and NaN, and neither represents all decimal fractions exactly.
Answer: It can represent negative and nonnegative integer values. Java's byte, short, int, and long use two's-complement ranges from -2n-1 through 2n-1-1 for an n-bit type. Zero is included.
Char is unsigned, ranging from 0 through 65,535. Ordinary integer arithmetic can overflow without throwing an exception; use appropriate checked operations such as Math.addExact when overflow must be detected. Signedness and overflow behavior should not be inferred from an object's storage size.
Answer: Both have a specified 64-bit value width. Long stores integral values exactly within its range; double stores floating-point values over a much wider range but cannot represent every long exactly.
public class NumericWidths {
public static void main(String[] args) {
long exact = 9_007_199_254_740_993L;
double rounded = exact;
System.out.println(Long.SIZE + " " + Double.SIZE);
System.out.println((long) rounded);
System.out.println(exact == (long) rounded);
}
}
This prints 64 64, then 9007199254740992, then false. Long-to-double is a widening conversion, yet it can lose precision. Equal width does not mean interchangeable representation.
Answer: No. A char is one unsigned 16-bit UTF-16 code unit. Many common characters occupy one code unit, but supplementary Unicode code points require a surrogate pair, or two chars.
A user-perceived character can involve multiple code points as well. String.length counts code units, while codePointCount counts code points over a specified range. Use code-point-aware APIs or appropriate text-boundary handling when the requirement is more than processing raw UTF-16 units.
Answer: No. They are two common invalid choices, but constructors also cannot be abstract, synchronized, native, or strictfp. Ordinary constructor modifiers consist of permitted annotations and an optional access modifier.
A constructor can contain a synchronized block when synchronization is necessary, but cannot itself be declared synchronized. Distinguish a modifier on the constructor declaration from modifiers on its parameters, such as final, or on the enclosing class.
References: Primitive and reference types, Conversions, and Constructor modifiers.