_
) isn’t a valid method name (it isn’t a valid identifier in Java)public static final int foo() throws IOException, SQLException {
// body
}
// return type must be written with method name followed by exception list; rest's order doesn't matter
public int foobar(){
return 1;
System.out.println("foobar"); // unreachable code; compiler error
}
public String getStr(){
// compiler error if nothing is returned in body
}
public --> everywhere
protected --> same class, other classes in the same package, and subclasses (even if subclass is in a diff package)
package access --> default; when we omit any access modifier; accessible only from inside the same package (class or subclass in the same package); if we try to access this from a subclass that's in a different package, there will be error (aka "package-private")
private --> accessible from within the same class only; not even its subclasses
Primitives & references vars --> Pass-by-value
Objects --> Pass-by-reference
Since there are no explicit references in Java unlike C++. We say everything is pass-by-value in Java which means a new reference variable is created in called method and not actual object/array is created in memory again.
Passing mutable types like List<T>
or Map<K, V>
:
public void addElement(List<String> listStr){ // new ref variable "listStr"; points to same list of string in heap
listStr.add("B");
}
public void bar(){
List<String> listStr = new ArrayList<>(); // list of string in heap
listStr.add("A");
addElement(listStr); // method call
System.out.println(listStr.size());
}
// Output: 2
Since wrapper class objects like String
and Integer
are immutable, their reference can’t be modified but can be re-assigned (re-pointed):
public static void foo() {
String s = "test";
change(s);
System.out.println(s);
}
public static void change(String s){ // new variable created (pass-by-value); ref to old
s = "eeee"; // re-assignment
}
// Output: test
------------------------------------------
public void foo(){
Integer n = 5;
increment(n);
System.out.println(n);
}
public void increment(Integer n){ // new variable created (pass-by-value); ref to old
n = n + 2; // re-assignment
}
// Output: 5
class Hello{
int a = 1; // instance variable
void foo(){
int b = 2; // local variable
}
}
final
final
on a reference variable won’t stop anyone from accessing and changing the value inside; its to stop changing the ref variable itselffinal
instance variables must be assigned a value before constructor/constructor chain finishesThe vararg syntax ...
only works in method declaration signature, compiler-error otherwise if used as a substitute for []
in class or method body.
Rules:
void foobar(String... str){ // or foobar(String ...str)
for(String s : str){
// code
}
}
// Call
String[] strArr = {"john", "doe"};
foobar(strArr)
foobar("foo", "bar")
// compiler-error
String... arr = {"a", "b", "c"};
static
variables and methods are allocated memory once and remain in scope till program endstatic
variables and methods can be accessed/called without creating an instance of the class they’re part ofclass Hello{
public static a = 5;
}
Hello obj = new Hello();
System.out.println(obj.a); // 5
obj = null;
System.out.println(obj.a); // still prints 5, no NullPointerException
static
fields can be updated from instance. Whenever instance updates, there is only one copy so it gets reflectedHello obj2 = new Hello();
obj2.a = 9;
Hello obj3 = new Hello();
obj3.a = 7;
System.out.println(Hello.a); // 7
static
methods can’t be overriden, since they are resolved using static binding by the compiler at compile time, they can be “hidden” thoughstatic
method can’t use this
keyword as there is no instance for “this” to refer to.static
variables but not the other way round. We can’t access non-static members from a static context without object reference.class Foo{
int a = 5;
static void foobar(){
a = 6; // not allowed
new Foo().a = 6; // allowed now since we provided an object ref
}
}
static
methods are almost like instance methods - overloaded, inherited, hidden, can have generic type params (unlike static variables). Exception - static interface
methods aren’t inherited to another interface or goto its implementing class.
class Hello{
static final int bamboo; // either initialize inline or use initializer block below
static { bamboo = 5;} // since we can't have constructors for static fields
}
import
import static java.util.Arrays.asList;
// can use without Arays.asList() now
static import java.util.Arrays.asList; // invalid! order is wrong
static
ness cannot be a distinguishing factor for overloading methods (compiler-error; same methods, so no overloading)static
methods can be overloaded by any other method since static
ness doesn’t matter in overloadingvoid foobar() { }
int foobar() { return 0; } // compiler-error; method already defined
----------------------------------------------------------------------
void foobar() { }
static void foobar() { } // compiler-error; method already defined
String
is matched if available over Object
)void foobar(String s){ } // 1
void foobar(Object o){ } // 2
foobar("yo"); // calls 1
foobar(88); // calls 2; autoboxes to Integer, then calls Object
void foobar(int n){ } // a
void foobar(Integer i) // b
void foobar(long l){ } // c
foobar(123); // calls a; if a is commented, then it calls b (autoboxing); if b is also commented then it calls c (promotion)
fooabr(123L); // calls c
void foo(int[] arr){ }
void foo(int... arr){ } // compiler error; duplicate method definition
foo(new int[]{1, 2, 3}); // can call either
foo(1, 2, 3); // calls varargs one only