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 } }
int var = 1;