static keyword.
class ClassA {
public void instanceMethod() { }
public static void staticMethod() { }
public void doSomething() {
// Accessing instance methods
(new ClassA()).instanceMethod(); // OK
(new ClassA()).staticMethod(); // OK - Warning: The static method staticMethod() from the type ClassA should be accessed in a static way
// Accessing static methods
ClassA.staticMethod(); // OK
ClassA.instanceMethod(); // Compiler error: Cannot make a static reference to the non-static method instanceMethod() from the type ClassA
}
}
class ClassA {
int var1 = 1;
static int var2 = 1;
public Integer instanceMethod() {
return var1 * var2; // OK
}
public static Integer staticMethod() {
Integer localVar1 = var2; // OK
Integer localVar2 = instanceMethod(); // Compiler error: Cannot make a static reference to the non-static method instanceMethod() from the type ClassA
return var1; // Compiler error: Cannot make a static reference to the non-static field var1
}
}
int doReturnPrimitiveType() {
int var1 = 0;
return var1;
}
Object doReturnReferenceType() {
Object obj = new Object();
return obj;
}
int doImplicitCastPrimitiveType() {
return 'c';
}
Object doImplicitCastReferenceType() {
return Integer.valueOf(10);
}
int doExplicitCastPrimitiveType() {
double var1 = 12.5;
return (int) var1;
}
Integer doExplicitCastReferenceType() {
Integer temp = Integer.valueOf(10);
Object obj = temp;
return (Integer) obj;
}
null, but only if the return type is a reference type.
Object doReturnNullValue() {
return null;
}
void type indicates that the method does not return any value.
void doReturnVoid() {
}
You can also use the return keyword to explicitly indicate the method returns nothing:
void doReturnVoid() {
return;
}
public class ClassA {
void foo(int param1, Integer param2, Object param3) {
}
void bar() {
int arg1 = 0;
Integer arg2 = 1;
Object arg3 = this;
foo(arg1, arg2, arg3);
}
}
Here are the rules for arguments to be accepted by the compiler:
void bar() {
int arg1 = 0;
Integer arg2 = 1;
foo(arg1, arg2); // Compiler error: The method foo(int, Integer, Object) in the type ClassA is not applicable for the arguments (int, Integer)
}
void bar() {
String arg1 = "0";
Integer arg2 = 1;
Object arg3 = this;
foo(arg1, arg2, arg3); // Compiler error: The method foo(int, Integer, Object) in the type ClassA is not applicable for the arguments (String, Integer, Object)
}
void bar() {
Integer arg1 = 0; // OK: Integer --> int
int arg2 = 1; // OK: int --> Integer
String arg3 = "my String"; // OK: String is a subclass of Object
foo(arg1, arg2, arg3);
}
public class ClassA {
static int doSumArgs(int... varParams) { // method accepts a variable number of int arguments
int total = 0;
for (int param : varParams) { // loop through all arguments
total += param;
}
return total;
}
public static void main(String[] args) {
System.out.println(doSumArgs(1, 2)); // Method call with two arguments
System.out.println(doSumArgs(1, 2, 3)); // Method call with three arguments
}
}
You can mix regular parameters with varargs.
void foo(String param1, Integer param2, int... varParams) { // OK
}
void bar(String param1, int... varParams, Integer param2) { // Compiler error: The variable argument type int of the method bar must be the last parameter
}
void multiVarArgs(int... varParams1, int... varParams2) { // Compiler error: The variable argument type int of the method multiVarArgs must be the last parameter
}
Note :
public class ClassA {
void foo(int... varParams) {
}
void bar() {
foo(1, 2, 3);
}
}
Will be transformed by the compiler into:
public class ClassA {
void foo(int[] varParams) {
}
void bar() {
foo(new int[] { 1, 2, 3 });
}
}
You’ll notice that the vararg declaration int... varParams becomes an array declaration int[] varParams.1, 2, 3 becomes an anonymous array new int[] { 1, 2, 3 }.public, private, or protected.
public class ClassA {
int instanceVar = 10;
void foo() {
int localVar = 5; // Local variable declaration
System.out.println(localVar); // OK
System.out.println(instanceVar); // OK - accessing instance variable
int instanceVar = 20; // This local variable shadows the instance variable
System.out.println(instanceVar); // Refers to the local instanceVar, not the instance field
}
void bar() {
int localVar;
System.out.println(localVar); // Compiler error: The local variable localVar may not have been initialized
}
}
Notes :
void foo() {
final int localVar = 3;
localVar = 4; // Compiler error: The final local variable localVar cannot be assigned. It must be blank and not using a compound assignment
}
var x;).var x[];).
class ClassA {
// var cannot be used for instance/static variables
var instanceVar1 = 1; // Compiler error: 'var' is not allowed here
static var staticVar1 = 1; // Compiler error: 'var' is not allowed here
void doSomething() {
var var1 = "abc"; // Inferred as String
var var2 = 1; // Inferred as int
var var3 = new int[] { 1, 2, 3 }; // inferred as int[]
var var4 = new ArrayList<String>(); // Inferred as ArrayList<String>
var var5 = Map.of("a", "b"); // Inferred as Map<String, String>
var2 = "xyz"; // Compiler error: Type mismatch: cannot convert from String to int
var var6; // Compiler error: Cannot use 'var' on variable without initializer
var var7 = null; // Compiler error: Cannot infer type for local variable y
// var cannot be used with arrays declared using bracket notation
var var8[] = { 1, 2, 3 }; // Compiler error: 'var' is not allowed as an element type of an array
var[] var9 = { 1, 2, 3 }; // Compiler error: 'var' is not allowed as an element type of an array
}
// var cannot be used for return types
var doReturnVar() { // Compiler error: 'var' is not allowed here
return 42;
}
// var cannot be used for method parameters
void doUseParamVar(var param) { // Compiler error: 'var' is not allowed here
}
}
Note that var is a reserved type name but you can still use it as a variable name: int var = 1;