Java Overall Flashcards
Java 4 Different Package Levels
Public, Protected, Default, Private
Private: to self
Public: to all
Default (Package Internal): same package //package/JDK/3rd party internal
Protected (Package + subclass Internal): package internal, but open to whoever extends my class
Client | | (closed library, no subclass allowed) Library (public) Library (default) Library (private) | | (Open library, subclass allowed) JDK (public, protected) JDK (default) JDK (private)
2 different Class Relationship: Package vs Inheritance
how they map to 4 access modifiers
*There is no parent accessing child class.
Then for classes 1) same package, yes inheritance //internal framework inheritance class 2) same package, no inheritance //internal framework inheritance class 3) diff package, yes inheritance //when you extends a JDK class, or a 3rd party library class 4) diff package, no inheritance //your class vs JDK
What does “transient” keyword do?
In a serializable object, “transient” keyword tells JVM not to serialize the value of the property (JVM will actually serialize with the default value). This access modifier can be used to “do not serialize secretes values to file”
note using with “static” (never serialized because it is not part of object) or “final” (always serialized) void the “transient”
What does “volatile” keyword do?
Volatile in java is different from “volatile” qualifier in C/C++. For Java, “volatile” tells the compiler that the value of a variable must never be cached as its value may change outside of the scope of the program itself. In C/C++, “volatile” is needed when developing embedded systems or device drivers, where you need to read or write a memory-mapped hardware device. The contents of a particular device register could change at any time, so you need the “volatile” keyword to ensure that such accesses aren’t optimized away by the compiler.
“abstract” method
A method declared with “abstract” means it will not have an implementation, forcing the class to be declared “abstract” so it cannot be instantiated.
interface method
A method declared inside “interface” has no implementation and thus is an “abstract” method.
All methods in regular interfaces are public and abstract.
functional interface
Started in 1.8
A functional interface
1) has one and only 1 method declaration.
2) [may] Also have “default” implementation or “static” implementation.
java.util.function.Function interface vs functional interface
“functional interface” is a specification
java.util.function.Function is an instance that satisfies “functional interface” specification, thus
java.util.function.Function is a Functional interface
It has one and only one declared method
public interface Function { public apply(T parameter); }
java.util.function.Function interface vs functional interface
“functional interface” is a specification
java.util.function.Function is an instance that satisfies “functional interface” specification, thus
java.util.function.Function is a Functional interface
It has one and only one declared method
public interface Function { public apply(T parameter); }
Consumer is a functional interface
It has one and only one declared method
public interface Function { public accept(T t); //consumes value t }
What is “default” keyword?
It means default “implementation” of a functional interface.
It does not mean “default access”, as default access is implied by lack of access modifier, not by the “default” keyword
java.util.function.Function interface, “apply()” method
java.util.function.Function is a functional interface with one and only one declared method
public interface Function {
public apply(T parameter); }
~~~
```
The “apply” is similar to javascript
objFUNC implements Java Function::apply() vs
C++ std::bind(objFUNC) vs
JS objFUNC.apply() or call()
They are all ways to invoke a function
JS
js_func.apply(obj, arg1, arg2…);
==obj.func(arg1, arg2)
‘obj’ is the ‘this’ pointer in the function, thus similar calling
C++
funcObj = std::bind(func, arg1, arg2…);
==funcObj(); //create a closure that includes func, and arg
==func(arg1, arg2)
java
A funcObj implements the Function::apply(arg1, arg2) functional interface.
Then funcObj() will invoke the function.
In this sense, java apply() is similar to C++ std::bind()
What is Consumer functional interface
Consumer interface declares one and only one method void accept(T t); like other functional interfaces.
This is a functional interface that represents a sink function that consumes a value without returning any value. A Java Consumer implementation could be printing out a value, or writing it to a file, or over the network etc.
It has “default” implementation “addThen()”
default Consumer andThen(Consumer super T> after)
which will chain consumers.
c0.addThen(c1).addThen(c2).addThen(c3).accept(); will invoke in sequence: /*first*/ c0.accept(v); /*then*/ c1.accept(v); /*then*/ c2.accept(v); /*then*/ c3.accept(v)
functional interface and lambda
Functional interface declares one and only one method. (with “default” or “static” helper methods).
Lamba is a function object that implements one and only one method.
Functional Interfaces Can Be Implemented by a Lambda Expression
Lamda to Functional Interface
is
Anonymous class to Java Interface
//This is a both functional and a regular interface interface HelloWorld { void foobar(); } HelloWorld helloworld = new HelloWorld() { @override void foobar() { System.out.println("Impl..."); } }
Helloworld helloworld = () -> {
System.out.println(“Impl…”);
}
Lamda to Functional Interface
is
Anonymous class to Java Interface
//This is a both functional and a regular interface interface HelloWorld { void foobar(); } HelloWorld helloworld = new HelloWorld() { @override void foobar(T parameter1, T parameter2) { System.out.println("Impl..."); } }
Helloworld helloworld = () -> {
System.out.println(“Impl…”);
}
lambda is syntax sugar of an object instance (of an anonymous class that implements a functioanl interface).
Since a functional interface has 1 and only 1 method, lamba can invoke the method without saying the method name.
Lamba is an “function object” instance that implement the corresponding “functional interface” with the “this” pointer bound in.
Helloworld helloworld=
(parameter1, parameter2) -> expression
Helloworld helloworld=
(parameter1, parameter2) -> {code block}
So invoked as helloworld(arg1, arg2),
not
helloworld.foobar(arg1, arg2);
lambda is an object instance (of an anonymous class that implements a functioanl interface) lambda can be passed/returned as any object lambda is an object instance of the "functional interface"
Constant Interface Antipattern
Do not put static constant in a interface
interface helloword {
static final int K = 10;
}
class A implements helloworld { //use K }
Constant Interface Antipattern
Do not put static final in a interface
interface IF {
static final int K = 10; //anti-pattern
}
class A { static final int K=10; //good pattern }
import static A.K;
Java outer class has full access to inner class members including private ones, and vice versa
WARNING!
https://stackoverflow.com/questions/1801718/why-can-outer-java-classes-access-inner-class-private-members
The “private” modifier on inner class and its members are “useless”, and it does not prevent application to access those members from an outer class object.
[*] Java Static Nested class is mostly a namespace purpose.
For nested static class, the enclosing class always has access to it (regardless if it is private)
“static Nested class” is can be considered as “implementation” class, that all its members including private members are accessible by the outer class.
[*] Non-static inner class if part of the outer class in storage. (It is like nested struct in C)
when you malloc() or new() a outer class, the storage space of inner class is also allocated
Objects of Non-static inner class must contain the “this” pointer to the outer class object (the two are “life-time bundled” instances)
(Objects of static nested class does not contain the “this” pointer of any outer class object— the two are life-time independent instances)
Outer object contains explicit reference to inner objects,
Inner objects contains the implicit “this” reference to the outer objects (initialized by JVM) (The explicit reference to outer object would be Outter.this)
For class Outter { int a; class Inner ( int a; //local a a = 10; //outer a Outter.this.a = 20; } }
Since the inner object must contain the “this” pointer of the outer object, the outer object must be created first.
Inner class object is created FROM outer object.
(
either
new Inner() inside outer class, or
new Outer().new Inner() from external class)
- can access all members (including private) of the outer object via its copy of the outer object’s “this” pointer
- Inner at class level and inner at local/function level
non-static inner class != nested struct in c
In C, a nested struct is created when outer struct is malloc() or new()’d. They co-exist and are co-located
In Java, inner object may or may not be created by the outer class. The outer object out-live the inner object if any. The inner object has an implicit copy of the outer object’s “this” pointer. They do not co-locate
[*] Outer object is fully visibie inside inner object via the inner object’s copy of the outer “this” pointer.
So watch out for variable hiding/shadowing
-
Lambda is syntax sugar for “new() Anonymous Class” (instance) for Functional interface which is special case of interface (one and only one method)
When not to use lambda?
lambdas lack names and documentation; if a computation isn’t self-explanatory, or exceeds a few
lines, don’t put it in a lambda.
Lambda is syntax sugar for “new() Anonymous Class” (instance) for Functional interface which is special case of interface (one and only one method)
When not to use lambda?
When to use Anonymous class (still useful in lambda era)
lambdas lack names and documentation; if a computation isn’t self-explanatory, or exceeds a few
lines, don’t put it in a lambda.
Lambdas are limited to functional interfaces (1 abstract method)
anonymous classes covers multiple abstract methods.
a lambda cannot obtain a reference to itself. In a lambda,
the “this” keyword refers to the enclosing instance,
In an anonymous class, the this keyword refers to the anonymous class instance.
Where method references are shorter and clearer, use them; where they aren’t, stick with lambdas
Static Method Reference are like function pointers (has no closure)
Bound Method Reference is like function pointer where “this” is bound and use to invoke the method (Instant.now()::isAfter)
lambda/anonymous are like function objects (has closure)
How to create genertic array in Java
This doe not work T[] a = new T[n];
T[] a = (T[]) new Object[n];
or
T[] a = (T []) Array.newInstance(Double.class, n);
Covariant, Contravariant, Invariant
Covariance (Java Array): accept subtypes
- Number[] accept Integer/Double…
- Integer[] is subtype of Number[]
Covariant (List extends T>): accept sub-types of T
* List accepts Integer
Contravariant: accept super-type of T
* List super Integer> accepts Number, Object
Invarinat (List) : Accept only exactly type T (generics)
- List accepts only Number
- List accepts only Integer
Covariant, Contravariant, Invariant
Co-variance (Java Array): accept subtypes
- Number[] accept anything Number( Integer/Double…)
- Integer[] is subtype of Number[] because Integer is subtype of Number
Co-variant (List extends T>): accept sub-types of T
* List is subtype of List
Contra-variant: accept super-type of T
* List super Integer> is super type of List
In-varinat (List) : Accept only exactly type T (generics)
* List is not compatible with List
Java Type Erasure: In Generics, enforcing type check only at compile time and discarding the element type information at runtime.
List only enforce that element assign to list is type T (exactly T or its subtype)
At run time all elements were treated as exactly T because its actual type info is discarded.
When using generics, Java checks for type safety at compile time, but throws away that information at run time.
(X) Stack[] a = new Stack[12]; //does not compile
(X) Stack[] a = new Stack<>[12]; //does not compile
(V) Stack[] a = new Stack[12];
(V) Stack[] a = (Stack[]) new Stack[12];
What is Stack$Node.class?
Java compile each class into a *.class file. The inner class is compiled to file names “outer$inner.class” pattern
what is Wide Inferface
An interface that contains more APIs than what the interface’s intended usage may need.
For example, a “Stack” only needs push/pop accessors. But Java.util.Stack has methods to access ith element (random access) or insert a tail (vs push to head)…these are unwanted operations, making java.util.Stack a wide interface. DO NOT USE.
what is Wide Interface (vs Narrow Interface)
An interface that contains more APIs than what the interface’s intended usage may need.
Wide Interface usually is less efficient because they have to “cover everything”.
Using Wide Interface violates “Principal of Parsimony”
For example, a “Stack” only needs push/pop accessors. But Java.util.Stack has methods to access ith element (random access) or insert a tail (vs push to head)…these are unwanted operations, making java.util.Stack a wide interface. DO NOT USE.
Note difference between Integer.valueOf() vs Integer.parseInt()
valueOf() returns Integer
parseInt() returns int
Mixed Type Comparison (both in C, Java)
Integer Promotion
Signed Promotion
constant-out-of-range-compare
COMPILE ERROR========:
C: char b = 0x90; //wrong because 0x90 is int
java: byte=0x90; //wrong because 0x90 is int
C: char b = (char)0x90; //ok
java: byte=(byte)0x90; //ok
what is b==0x90?
It is false because constant 0x90 is promoted integer.
then ‘b’ is promoted to integer (144) but b is signed, so b is promoted to -112
-112 != 144
C compiler gives warning “constant-out-of-range-compare”
Inner class can be at class level or function level
class level or function level only affect the “scope” of the class (I.e. function level class is only visible inside the function).
For the inner class itself, regardless at which level, it has the “this” pointer of its containing class.
============================================
Either way inner object contains a copy of the “this” pointer of immediate enclosing object which contains the “this” pointer of its enclosing object and so on
Therefore inner–inner–inner chain forms a chain of “this” pointers.
Inner object contains the “this” pointer of its enclosing object…
This is like the “lambda Capture of [this]” in C/C++ or “Closure” in Javascript
A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives you access to an outer function’s scope from an inner function.
In C++, what is captured must be explicitly specified in the lambda function:
[&, this]() { /*access m_x and x*/ }();
In JAVA, inner object, when created, automatically capture the “this” pointer of outer object, giving inner object full access to the outer object.
In JavaScript, closures are created every time a function is created, at function creation time.
Inner object “captures” the “this” pointer of outer object
-
String Interning (Java)
In computer science, string interning is a method of storing only one copy of each distinct string value, which must be immutable
Java String::intern() method is a native method (pool maintained by JVM)
Java Substring (a copy or a aliasing)
Upto 1.7, Java substring is a aliasing the original copy (with different start/stop index)
Start 1.8, java substring makes a copy of the original string.
How can java substring() cause memory leak
When having substring() sharing the the underlying string with the original,
1) create a string of 1G chars A
2) create a substring of 1 char S
3) A=null
4) since S shares the reference with A, then the 1G char array is kept around for the S
I.e. 1G char (2G bytes) is kept in memory for use of 1 char (2 bytes). This is memory leak.
Java memory leak possible?
yes
1) when memory allocated are more than what is bein g used (e.g. java substring problem)
2) reference is not null’d after use (loitering)
java.math.BigInteger
(Java does not have operator overload)
(It is a design decision by the java creator)
+,-,*,/ is done via methods add()/multiply()/divide()
Java does not have operator overload except for string +
It is a design decision by the java creator
-
Tricky Object compare
Rule Of Thumb:
Always use “equals()”
Never compare two objects with “==” unless you only want to compare Object Identify or Reference/Pointer Equality
”==” always compare Reference Equality
Watch out for Interning string or **autoboxed* objects
https://stackoverflow.com/questions/1514910/how-to-properly-compare-two-integers-in-java
Integer x = 10; //small value
Integer y = 10; //small value
Integer a = 102102; //large Value
Integer b = 102102; //large Value
x == y (True, by Reference Equality)
a == b (False, by Reference Equality)
Correct comparision: a.intValue() == b.intValue() x.intValue() == y.intValue() or x.equals(y) a.equals(b)
When comparing primitive type vs boxed type, the boxed type will be unboxed first.
Integer a = 10;
Integer b = 10;
a == 10 is true as “a” will be unboxed first
a == b is wrong way of comparison as no unboxing will be done so actually will be comparing Reference Equality
default impl of Object.equals() is Reference Equality, not Value Equality
primitive array int[].equals() thus is default Object.equals()
Thus we need Arrays(int[]) which is value Equality
Object.java
public boolean equals(Object obj) {
return (this == obj);
}
try { ... return true; } finally { ... return false; }
“return/break/continue” causing try{} to complete “abruptly”.
finally gets executed whenever code leaves try{} block.
“return/break/continue” causing finally{} to complete “abruptly”
The return in finally{} will override the return from try{}
called abrupt completions because they prevent the program from executing the next statement in sequence
In summary, every finally block should complete normally, barring an unchecked exception. Never exit a finally block with a return, break, continue, or throw, and never allow a checked exception to propagate out of
a finally block.
try { ... return true; } finally { ... //no abrupt completion, so the "return" value from try{} is kept. }
T…
3 dots (ellipsis varargs) can be provided by
1) a sequences of object of type T
2) an array|List|Stream
varargs
T…
when no args is given for the ellipsis, the method is called with an array of length 0.
(This ellipsis serves as optional args in C)
3 dots (ellipsis varargs) can be provided by
1) a sequences of object of type T
2) an array
(Y) array because the varargs is access as an array inside the method
(X) not Stream or List
When you do Arrays.asList(new Random().ints(10)) You are creating a list of 1 element which is an object of IntStream. List cannot be accessed as array inside the method.
You are NOT creating a list of 10 integers.
A string constant pool is a separate place in the heap memory where the values of all the strings which are defined in the program are
"abc" == "abc" --> (true), same object in string constant pool new String("abc") == new String("abc") ---> false
Outer class has full access to its Nested/Inner class and members and vice versa.
Java access control to Nested or Inner class and its members only applies to the global classes, not to each other
From inside nested/inner class, full access to outer class from outer class, full access to inner/nested class.
Therefore, the “static nested” class should not be used for “namespace” purpose because it opens up outer class to the nested class.
Nested/inner class are considered part of “interface and implementation” of the outer class.
use “package” alone for namespace.
java Streams naturally supports mapReduce
(map, flatMap, then reduce)
Use the reduce operation when you’ve got a collection of values and you want to generate
a single result (min, max, sum, count etc)
In reduce, every iteration is a reduction
Input: element, current reduction result
output: new reduction result
* <pre>{@code * int result = identity; * for (int element : this stream) * result = accumulator.applyAsInt(result, element) * return result; * }</pre>
Higher-order functions in functional programming
A higher-order function is a function that either takes another function as an argument or returns a function as its result.
(Function as first class objects)
Functional functions are side-effect free
(Pure functions)
(even a printf is a side-effect (on console))
Functional interface describes what needs to be done not how to do it. Another aspect of getting to the what and not the how is the idea of a side effect–free
function: no changing of global states.
Higher-order function example
public static Comparator comparingInt(ToIntFunction super T> keyExtractor) {
Input: a function object (lambda expression, type|interface ToIntFunction) that implements
int applyAsInt(T value);
I.e. Input is a functor that extract T as int
Output: a comparator functor that uses input functor as the key extractor)
Java8 :: operator
MainClass::foo
introduced as “method reference” to foo and can be used as a functor.
::
Java8 :: operator MainClass::foo introduced as "method reference" to foo A syntax sugor for lambda expression: (call the foo() on the lambda argument) (MainClass x) -> x.foo()
::
Inteface vs (Interface with Default implementation or Abstract class)
Interfaces give you multiple inheritance but no fields, while abstract classes let you inherit fields but you don’t get multiple inheritance. When modeling your problem
domain, you need to think about this tradeoff, which wasn’t necessary in previous versions
of Java.
Interface (default method) vs Abstract class (method)
Interface vs (Interface with Default implementation or Abstract class)
you can implement multiple interfaces but not inherit multiple abstract classes.. When modeling your problem
domain, you need to think about this tradeoff, which wasn’t necessary in previous versions
of Java.
Comparator vs Comparable
A Comparator is an interface external to class T. A Comparable is an object T's internal behavior.
A Comparator can implement its compare() with Comparable object's compareTo() But usually if T is comparable you don't need Comparator. You need comparator if you get a 3rd party class that is not Comparable.
interface Comparator { int compare(T o1, T o2) { o1.compareTo(o2); } }
interface Comparable { int compareTo(T o) }
Instance and class variable default initialization
Instance and class variables don’t require us to initialize them. As soon as we declare these variables, they are given a default value as follows:
class FOO { String bar; int i; boolean b; FOO() { /* bar is already init'd to null * i init'd to 0 * b init'd to false * before constructor is invoked */ } }
length() vs size()
String.length()
array. length
List.size()
Collection.size()
We can see immutable object (string, array) length is fixed/constant.
Immutable object (list/collections) size changes when items are added or removed.
What is the RandomAccess marker interface?
What is marker interface?
test
Comparable vs Comparable
The signature of method is compareTo(T v)
For Comparable the the Signature is
boolean compareTo(T v)
you can only compare against T
For Comparable, (raw type) the signature is boolean compareTo(Object v) you can compare against anything
Java Stream is Graph Execution
Like Tensorflow Graph Execution vs Eager Execution
Like SQL Graph Execution vs Eager Execution
Java stream methods are Lazy Methods
Why Override method must have equal or more access modifier?
You can not make access modifier more restrictive, because that would violate the basic rule of inheritance that a subclass instance should be replacable in place of a superclass instance.
If A extends B
Then A can be used in place of B, thus A must make B’s method available at same or more.