Skip to content

Instantly share code, notes, and snippets.

@djangofan
Last active August 7, 2021 16:46
Show Gist options
  • Save djangofan/a8b3e82e585525467c454515a8fb9ecf to your computer and use it in GitHub Desktop.
Save djangofan/a8b3e82e585525467c454515a8fb9ecf to your computer and use it in GitHub Desktop.
java acp exam 1.8 study notes
Java 1.8 ACP Exam Study Factoids
------------------------
http://docs.oracle.com/javase/specs/jls/se8/html/index.html
http://stackoverflow.com/documentation/java/topics
http://www.programcreek.com/simple-java/
https://www.compilejava.net/
IOException and NumberFormatException are always thrown programmatically while other exceptions such as ArrayIndexOutOfBounds, ExceptionInitializerError, and NullPointerException are thrown by the JVM at runtime.
Initialize all local variables (unless they arent used)!
Don't try to catch an Exception that the compiler knows wont occur... the compiler prevents this.
Yes, a class can have a fully qualified import statement that imports itself. Also, if your in the same package, you can simply: import OtherClass;
The reference controls if you have access to protected methods! Make sure the reference is to a object that extends the class in the other package! Tricky!
b==a when Object b is assigned to Object a
Exception example:
public class HelloWorld
{
public static void main(String[] args)
{
try{
test();
} catch (YException y){
y.printStackTrace();
} catch (XException x) { //warning: unreachable catch clause, thrown type YException has already been caught
x.printStackTrace();
}
}
static void test() throws YException {
System.out.println("Test");
}
}
class XException extends Exception{}
class YException extends XException{}
Another exception example:
public class HelloWorld
{
public static void main(String[] args)
{
try{
test();
} catch (Exception y){
y.printStackTrace(); // this wont stop the program
//return; // this will stop the program
throw new RuntimeException("ok"); // this will stop the program
}
System.out.println("Got here."); // this might not print
}
static void test() throws Exception {
System.out.println("Test");
throw new Exception("stopit");
}
}
float x = 10d; // will not compile
A static final var cannot be initialized in a regular initialization block, it must be on the same line or in a static initialization block.
String x;
System.out.println(x); // prints 'null'
Polymorphism only allows subclasses to be added to a list defined like this:
List<Whale> w = new ArrayList<>();
Where Narwhale extends Whale and Whale implements HasTail and Whale extends Mammal
So, you can add Narwhale, null, or Whale to the list. You can't add Mammal, HasTail, or Object.
CAREFUL: dont call 'new' on a abstract class or interface
In a for-loop without braces, be careful because the index var is not in scope after the statement.
These 2 are both ok:
StringBuilder s1 = new StringBuilder(5);
StringBuilder s2 = new StringBuilder("p");
As of Java 8, which of the data types are permitted as the decision variable for a switch?
A: byte, short, char, int, Enum, String, Byte, Short, Character, and Integer
Not allowed: Long, long, double, Double, float, Float
Why? Long and Double are 64-bit and float/double are decimal.
class Apple {
public String color="red";
}
public class Main {
public static void main(String[] args) {
Apple apple = new Apple();
System.out.println(apple.color); // red
changeApple(apple);
System.out.println(apple.color); // green
}
public static void changeApple(Apple apple){
apple.color = "green";
}
}
Pre-increment: ++x
If you want the new value of an increment operator to be used in an expression after it is updated.
In other words, ++x evaluates to (x add 1) immediately, not after expression is evaluated.
System.out.println(1 + 2 + "3" + 4 + 5); prints 3345
If you mark a instance variable private, it's still accessible via public getters, but it can be hidden by extending class and declaring a variable of the same name.
public static class Hello { // compiler wont allow this on a top level class definition
StringBuffer and String are thread safe. StringBuilder is not threadsafe unless contained in a local variable context.
StringBuffer is slower because its threadsafe, compared to StringBuilder
NOTE: I suspect that since local vars are effectively private and final, they are thread-safe?
https://www.youtube.com/watch?v=W8nNdNZ40EQ
String is final but NOT StringBuilder, StringBuffer, arrays, nor ArrayList
If String were not final, you could create a subclass and have two strings that look alike when "seen as Strings", but that are actually different.
System.out.println("hmm".substring(1,2)) prints the middle char 'm'
new StringBuilder("surprise").insert(3, "!!"); inserts before the p NOT after
== proves, by default, 2 references point to the same object. Object.equals can be over-ridden to have a different behavior.
- Object.equals could compare (if implemented) objects on the heap, who are probably not at the same address
- == compares memory address and so for 2 Strings, they could point to the same object on the heap, or the same address
- we prefer .equals to compare Strings because it works even if someone created a dupe string object on the heap with 'new String('already on heap')'
Methods contain 7 items: access modifiers, optional specifiers, return type, method name, parameter list, exception clause, and method body
package private means code in the same package can call it
its legal to say 'public abstract interface' but it is reduntant to use the abstract modifier
NOTE: interface must be public/package-private to be visible in another package (protected/private is not allowed)
interfaces are NOT abstract but they act like it. interfaces can contain un-implemented public abstract methods , public default methods, static methods, and public static final variables.
interface variables are all public, static, and final, implicitly
a class cannot extend an interface, it must implement!! (because its not a class)
Java interface static method is part of interface, we can’t use it for implementation class objects.
a reference to a class may be automatically boxed-up and used as a reference to a superclass (or interface) without a cast. This is polymorphism. Sub-class requires a cast-down.
Use instance-of operator just to be sure before you cast OR provide a constructor in the sub-class that further initializes/checks missing class members
interface IMe {
default void test(){
System.out.println("Default");
}
}
public class Hello implements IMe{
public int x = 2;
public void test(){
System.out.println("Test" + x);
}
final static public void main(String[] args){
System.out.println("It compiled and ran.");
new Hello().test();//2
SubHello sh = new SubHello();
sh.test();//10
Hello h = new SubHello();
h.test(); //10
//h.getX();//error
System.out.println("Var"+ h.x);// 2
System.out.println("Get" + sh.getX());//10
}
}
class SubHello extends Hello {
public int x = 10;
public void test(){
System.out.println("Test" + x);
}
public int getX(){
return this.x;
}
}
this() can be the first line of a constructor but the call will eventually resolve to calling super() anyway
unchecked exceptions extend RuntimeException.
checked exceptions extend Exception
try statement can have zero catch clause if it has a finally. remember! ONLY 1 catch clause will get caught before the finally.
YES, final static is ok to come before public in a method declaration . main() method can have a final modifier optionally.
Casting to a parent class/interface, you will lose access to sub-class variables and methods.
SubClassX sc = new SubClassX();
ClassX c = (ClassX)sc;
int x = c.scInt; // not allowed
c.scMethod(); // not allowed
abstract is not valid on a field member
int 1____3 = 13 , yes it does
int hex = 0xCAFE_BABE is ok
NUMBERS:
double cannot be implicitly narrowed to a float
12,573 = radix 10 polynomial 1*10^4 + 2*10^3 + 5*10^2 + 7*10^1 + 3*10^0
base2 is useful for binary arithmetic operations can be implemented using boolean logic
Let's take a look at a number like 3510. The first number less than or equal to 35 that is a power of 2 is 32 -- that's 25.
So 35 = 32 + 3. We won't use 16, 8, or 4, but we will use use 2 and 1. So 35 is 1*2^5 + 0 * 2^4 + 0 * 2^3 + 0 * 2^2 + 1*2^1 + 1*2^0,
which we'll write as 100011
the integral types (byte, short, int, and long) [not double or float] can also be expressed using the binary number system
when defining a float with binary, no need to put an 'f' on the end. thats only necessary with decimal system and hex
float x = 010_000f; is valid but it is not octal even though it starts with a 0. It is interpreted in decimal.
d and D are ok on a double
float dx = 0xff; is valid but the f here is not for indicating that it is a float but is interpreted as the hex digit F
HEX, aka base-16 :
Put 0x or 0X in front of the numbers. Calculate left to right!
Use the letters A to F (or a to f) to represent digits with values 10 to 15, respectively.
int hexValue1 = 0x100;
int hexValue2 = 0x1234;
int hexValue3 = 0xDEAF;
int hexValue4 = 0xCAB;
long hexLongValue = 0x0FL;
0x12 = 2 + (1 * 16) = 18
0x99 = 9 + (9 * 16) = 153
0xFB = 11 + (15 * 16) = 251
OCTAL, aka base-8:
Octal values is base 8, calculated left to right
Legal digits in an octal literal can be from 0 to 7
Octal literals are with a leading zero, for example 035 and 067
int octValue = 036;//24
Integer.toOctalString(44);//054
8 = (1 x 8) + ( 0 x 1) = 10
Octal example:
TO get 545, divide 8 into 357 repeatedly, taking remainder divided by 8, etc.
decimal value '357' = (5 x 8^2) + (4 x 8^1) + ( 5x 1) = 0545 base-8/octal
BINARY, aka base-2:
"0xD" (radix 16), "13" (default radix 10), "015" (radix 8) and "b1101" (radix 2) are four different representations referring to the same number.
byte aByte = (byte)0b00100001;
long aLong = 0b1010000101000101101000010100010110100001010001011010000101000101L;
int x=0b101;
int y=0b110;
if ((instruction & 0b11100000) == 0b00000000) { ... (a base-2 example)
Try converting these base2 numbers from binary to decimal:
byte fourTimesThree = 0b1100; //12
10 = (1*2^1) + (0*2^0) = 2+0 = 2
11 = (1*2^1) + (1*2^0) = 2+1 = 3
111 = (1*2^2) + (1*2^1) + (1*2^0) = 4+2+1=7
10101= (1*2^4) + (0*2^3) + (1*2^2) + (0*2^1) + (1*2^0)=16+0+4+0+1=21
11110= (1*2^4) + (1*2^3) + (1*2^2) + (1*2^1) + (0*2^0)=16+8+4+2+0=30
DECIMAL, aka base-10:
Integer a = 126; //no boxed up conversion, re-use memory address
Integer b = 126; //no boxed up conversion, re-use memory address
System.out.println("Are they equal? " + (a == b)); // true
Integer a1 = 140; //boxed up conversion
Integer b1 = 140; //boxed up conversion
System.out.println("Are they equal? " + (a1 == b1)); // false
System.out.println("Are they equal? " + (new Long(5) == new Long(5))); // false
Class with static variables still need to be imported if you want to use their non-static members. 'import static com.pack.Class.*;' is not good enough.
char and short would need to be cast to each other. they dont box up nor do they cast down automatically (verified; lossy conversion error)
there is no auto-cast down to char from int BUT it will autobox up to int from char
anything bigger than INT must be cast down to int or smaller its not automagic (lossy conversion error)
~ , Binary Ones Complement Operator is unary (returns a value?) and has the effect of 'flipping' bits.
The operator += and *= and /= and <<= and -= are all able to auto-type-cast, as opposed to normal arithmatic operators:
E1 = (T)((E1) op (E2)) is how *= or += is evaluated
this is OK:
short x = 3;
x += 4.6; [compiler calculates like this: x = (short)(x + 4.6); // rounds down to return 7, lost of precision on conversion ]
local vars MUST be initialized before being used (because they are implicitly final)! declaration and initialization NEED NOT be on the same line! compiler requires this.
In Java, class and instance variables assume a default value (null, 0, false) if they are not initialized manually. However, local variables don't have a default value.
int a; // This is a declaration
a = 0; // This is an initialization
int b = 1; // This is a declaration and initialization
modulus can be used on floating points operands also. For example, 5.5 % 3 = 2.5
Values of type boolean cannot be cast/converted to any other types.
BYTE (total range = 256):
Minimum is larger than max because max includes 0.
Minimum value is -128 (-2^7)
Maximum value is 127 (inclusive 0) (2^7 -1)
CHAR:
char data type is a single 16-bit Unicode character
Minimum value is '\u0000' (or 0)
Maximum value is '\uffff' (or 65,535 inclusive)
This is ok. float f = -123;
Long and Float are signed in Java but capable of being unsigned.
Colloquially, "unsigned integer" means a 32-bit int or 64-bit long value where all the bits are interpreted as contributing to the entire magnitude.
Integral types means byte, short, int, long
~ Operates only on integral types
Floating point types are float (32bit) and double (64bit)
Character type char (stored as a interned ref on the heap sorta like a String)
unlike &&, & will not "short circuit" the expression if used on boolean parameters.
& can have integral as well as boolean operands.
The modulus operator can be used with integers and also floating points also.
Operator & can be used with boolean operands and also Integral.
Operator ~ only works with Integral types.
When both operands of an operator &, ^, or | are of a type that is convertible to a primitive integral type, binary numeric promotion is first performed on the operands.
I still don't understand this:
0xff00 & 0xf0f0 is 0xf000
0xff00 ^ 0xf0f0 is 0x0ff0
0xff00 | 0xf0f0 is 0xfff0
For &, the result value is the bitwise AND of the operand values.
For ^, the result value is the bitwise exclusive OR of the operand values.
For |, the result value is the bitwise inclusive OR of the operand values.
A: http://stackoverflow.com/questions/41538838/why-would-we-use-bitwise-operators-between-2-numbers
Used to check flags when passing multiple values to a method. So, if you want to pass multiple integer args to a method with a OR operator, for example. The OR operator , in a way, combines the args and they can be checked for existence inside the method.
The arithmetic operators *, / and % have the same level of precedence, but left to right.
Keep in mind that 'static methods' are not overridden, they are shadowed! Non-static methods can be overridden. (exception: static methods in interfaces belong to the interface only, not the implementing class)
In a try-finally, an exception thrown in try is ignored/not-handled by a catch block and so all you get is what is in the finally block.
Its ok to declare a subclass variable private when its super class had the same variable be public. The parent class wont need to access the private sub-class variable with the same name.
- the parent class has a shadowed version of that var for itself
- the methods in each class can only access the var in the same class
There is no 'this' available in 'public static void main()' and so none of the this.x are valid in a class having only that method (and not instantiating the current object).
"for (i=0 ;; i++) break;" iterates only once because of the break so the value of i remains 0 until after the expression.
the i++ is never executed unless the middle expression was true at least once!
After this loop ends, the value of i is 3 (not 2!!) : "for(i = 0; i < 3; i++){}"
"if (b2 = b1 != b2) {" evaluates right to left because of assignment
Ex: expression "i= 10" returns a value of 10, equal to left hand side of assignment
Compiler will not generate a default constructor if the programmer defined 1 or more constructors. A no-args constructor implicitly calls the no-args constructor of the super class first; Via hidden/implied call to super().
A subclass may choose not to override abstract methods, in which case, the subclass will have to be abstract too.
ArrayList is in java.util, not java.collections (which does not exist). java.util package is not imported automatically
When you use System.out.println(exception), a stack trace is not printed. exception.printStackTrace() does that. You can also get the stack trace array via: e.getStackTrace()
Each array object has a member variable named public final length of type 'int' that contains the size of the array.
length --- arrays (int[], double[], String[]) ---- to know the length of the arrays.
length() --- String related Object (String, StringBuilder etc)to know the length of the String
size() --- Collection Object (ArrayList, Set etc)to know the size of the Collection
count() --- for a Collection, might return less than length() if there are nulls
Never use super.super.whatever. Thats not legal. You will go to jail.
Where C extends B, and B extends A, and all 3 classes have the same public m1() method, no matter what you do, in class C you can only access C's m1() even by casting this to B or A. Non-static methods are overridden, not hidden.
These declarations are ok but look funny:
int ax = 'c'; // any char can/will auto-box up to int
char cx = 6;
Int ax is obviously ok; unicode number can be assigned to an int. Char cx is ok because a narrowing primitive conversion may be used at compile time if the type of the variable is byte, short, or char, and the value of the constant expression is representable in the type of the variable.
In a switch statement, the case constants must be assignable to the switch variable.
The case label must be literal, enum, or finalized at compile time.
NOTE: compiler catches problem ONLY when case-label is too big to fit into switch expression, not the other way around
NOTE: if case-label is not final, youll get compile error 'error: constant expression required'
NOTE: BEWARE of final var passed into function as that is not final at compile time and switch wont consider it final.
Classes and array types are known as reference types. Primitive types are linked in JVM by value, not by reference.
null is a empty-object that you can reference to; null is not a link by value in JVM. The null value is unique in that it can be assigned to a variable of any reference type whatsoever.
int i = null; //not legal!
LocalDate, LocalTime, and LocalDateTime have static factory methods.
DateTime classes have private in-accessible constructors and lack setters.
Gregorian calendar is in java.time.chrono package, as ISO-8601 standard. ZonedDateTime or OffsetDateTime have time zone info in them.
DateTime classes are immutable. Make sure each static method you call assigns back to a variable each time; you can chain but make sure you assign back to the same var on the left.
Dont confuse old SimpleDateFormat class with new static factory DateTimeFormatter.
Default date pattern is : YYYY MM dd
You CANNOT chain with Period class, using the '.of' factory methods!!! You can chain with the copy methods such as .minusMonths(3), so, this would work:
Period p = Period.ofYears(1).minusMonths(3).minusDays(3);
System.out.println(p);//P1Y-3M-3D
All 'final instance variables' must be initialized either in an instance block or in a constructor.
method public static long main(String... args) will throw a NoSuchMethodError at runtime, not at compile time.
The main method must return void, so says the runtime.
A double/float/long/boolean cannot be used in a switch statement
Why is -Integer.MIN_VALUE still come out to Integer.MIN_VALUE rather than Integer.MAX_VALUE ?
A: Because of silent integer overflow: Integer.MIN_VALUE is -2^31 and Integer.MAX_VALUE is 2^31-1, so -Integer.MIN_VALUE is 2^31, which is Integer.MAX_VALUE + 1, which by definition is too large for an integer.
Using this.var is ok for static variables as long as you have a class instance initialized.
System.out.println(new Hello().staticInt); //ok
An object assigned to null can be garbage collected UNLESS some other reference was also pointing at the object on heap.
FYI: This method wont work as expected without a 'this.' reference:
private int myValue = 0;
public void showOne(int myValue){
myValue = myValue;
System.out.println(this.myValue);
}
NOTE1: this is because of scope of method param shadowing the class var!! normally a variable is accessible without using this keyword.
NOTE2: 'this' reference is not available within a static method.
A char value can ALWAYS be assigned to an int variable, since the int type is wider than the char type
A narrowing primitive auto-conversion may be used if all of the following conditions are satisfied:
- The expression is a constant expression of type int (not a variable! implicit narrowing wont occur on a variable!)
- The type of the variable is byte, short, or char.
- The value of the expression (which is known at compile time, because it is a constant expression) is representable in the type of the variable.
Note: that narrowing conversion does not apply to long or double.
so, char ch = 30L; will fail although 30 is representable by a char.
This is oK: char ch = (int)30L;
The narrowing occurs at compile time.
Be aware of exception thrown during a initializer block, as it may be wrapped in a ExceptionInitializerError rather than throwing exception.
Lambda:
(parameter list [with type or not]) OR single_variable_without_type -> { regular lines of code } OR just_an_expression_without_semicolon
http://enthuware.com/index.php/home/115
If you enclose your method body within curly braces, you must write complete lines of code including the semi-colon.
FYI, if the method is supposed to return a value, then you must include a return statement just like you do in a regular method if you are using the curly braces syntax.
parenthesis around parameter list is ONLY optional when parameters are just 1 and it doesn't have a type
Widening conversions, auto-box (no lossy info loss):
byte to short, int, long, float, or double
short to int, long, float, or double
char to int, long, float, or double
int to long, float, or double
long to float or double
float to double
note: double cannot be implicitly narrowed to a float even though the value is representable by a float. 64bit to 32bit conversion makes this problematic.
int a = 10;
a += (a =4) is same as a = a + (a=4).
First, a's value of 10 is kept aside and (a=4) is evaluated. The statement (a=4) assigns 4 to a and the whole statement returns the value 4. Thus, 10 and 4 are added and assigned back to a.
A class cannot override the super class's constructor Because constructors are not inherited.
Note that a floating point number cannot be written in Octal. Therefore, float x = 010_000f; is valid but it is not octal even though it starts with a 0. It is interpreted in decimal and so is equal to 10,000.0 rather than 4096 .
A floating point number written in binary or hex cannot use any suffix for float. But a floating point number written in decimal can use the floating point suffices f, F, d, and D.
Invalid: float d = 0 * 1.5; // after resulting in double, cannot narrow down to float
Valid: float f = -123; // can autobox up to float -123.0
Fields in an interface are implicitly public, static and final.
In Java DateTime, Period.ofMonths(1).ofDays(1) will give you a Period of only 1 day because the methods are static and '.of' methods do not chain.
An interface can have a static method but the method must have a body, just like a default method. Since the interface is not itself associated with an instance of a class, its only accessible in this case via reference of the class-name.
You can declare anything that is a Throwable or a subclass of Throwable, in the throws clause, including Error, Exception, and RuntimeException. Throwable is their parent class.
An overriding method can throw a subset of the exception or subclass of the exceptions thrown by the overridden class. Having no throws clause is also valid since an empty set is a valid subset.
If a switch has a default case label at the top, that doesn't mean labels below it are unreachable by compiler. If the case is an exact match to a label, it will jump over the default label.
Its unusual, but ok, if the class has a method with the same name as the class. There is no rule against that.
To override a method in the subclass, the overriding method (i.e. the one in the subclass) MUST HAVE:
- same name
- same return type in case of primitives (a subclass is allowed for classes, this is also known as covariant return types).
- same type and order of parameters
- it may throw only those exceptions that are declared in the throws clause of the superclass's method or exceptions that are subclasses of the declared exceptions. It may also choose NOT to throw any exception.
- The names of the parameter types do not matter. For example, void methodX(int i) is same as void methodX(int k)
NOTE: A method can throw any RuntimeException (such as a NullPointerException) even without declaring it in its throws clause.
Checked Exceptions IOException and FileNotFoundException make sense to require handling since a program might require external resources in order to work. Other lighter exceptions, such as NullPointerException and ClassCastExeption are suitable as un-checked RuntimeExceptions because they may not cause program failure per-se. This is philosophical.
For all subclass exceptions of RuntimeException, you are not required to declare throws in the method signature. Also, its not required to catch them inside the method either since RuntimeException will catch problems. Ex: TimeoutException is a checked exception and extends Exception and so its always required to catch around a Thread.sleep(x).
String replace() method returns the same String object if both the parameters are same, i.e. if there is no change.
This is true: "String".replace('g','g')=="String"
boolean class variables (static) default to false if not intialized
yes, compile can throw multiple exceptions. it doesn't stop at the first failure.
Overriding method may be made final.
The overriding method can only have more visibility , not less.
For imports: import static only, not static import
Values of type boolean cannot be converted to any other types.
long g = 012 ; - a valid octal number, boxed up to a long
static methods can never be abstract (neither in an interface nor in a class).
An interface can have a static method but the method must have a body.
An interface can redeclare a 'default' method and provide a different implementation, or not.
interface abstract methods cannot have body
Within an extending interface, you cannot redeclare a non-default abstract method that overrides a super interface default method (having an implementation). You can redeclare the default method with a different implementation. You cannot reduce the accessibility of the method. protected and private not allowed and package-private is implied to be public.
Interface methods are implicitly public & abstract.
when the class (or the superclass) of an object does not override the toString method, Object class's toString is used, when fed to println method, which prints the name of the class + @ sign + hash code of the object.
For an array: Paper[] papers -> "[LPaper;@7852e922"
For a byte array .toString() : "[B@<hashcode>"
For a Byte[]: [Ljava.lang.Byte;@6d06d69c
For String[]: [Ljava.lang.String;@7852e922
for "val:" + char[]: val:[C@4e25154f
for char[] : abcd (because System.out.println(char[] x) is used)
NOTE: for Boxed up types, they implicity call .toString() by default. for primitive array objects, you need to specify calling .toString on the object, otherwise it prints internal values
Yes, you can override a parent class method with a new abstract method, not having a default implementation but it has to be done within a abstract child class.
str1.equals(str1=str2) : str1.equals is evaluated (on the left side of .) before str1=str2
so, "cc".equals("cc"="dd"); evaluates to false
is OK: final static private double PI = 3.14159265358979323846 ;
not a valid declaration in a class: abstract int t ;
Always remember: Methods are overridden and variables are shadowed.
example: Baap b = new Beta();
1. always uses methods in Beta
2. always uses values defined in Baap, accesses shadowed variables after cast down
public class Test{
public static void main(String[] args){
java.time.LocalDate dt = java.time.LocalDate.parse("2015-01-01");
System.out.println(dt); // 2015-01-01
dt = dt.minusMonths(1).minusDays(1);
System.out.println(dt); // 2014-11-30
dt = dt.minusMonths(1).minusDays(1).plusYears(1);
System.out.println(dt); // 2015-10-29
java.time.LocalDate dt1 = java.time.LocalDate.parse("2015-01-01").minusMonths(1).minusDays(1).plusYears(1);
System.out.println(dt1); // 2015-11-30
}
}
When you add a Object to a ArrayList, those objects passed in can still be modified later without accessing via the ArrayList. They are passed by reference (reference to values).
final is a valid modifier for the standard main method.
A public class declaration must only exist in a file by the same name
Use the most specific overloaded method. If you have 3 methods that take either Object, IOException, and FileNotFoundException, and you pass a null, then it will try to use the method taking FileNotFoundException !!!
Yes, n[0]++ will increment the value held within the array. It increments the reference to the value.
In a try clause, even if the break takes the control outside of the block, the finally clause will be executed!!
You can apply a label to any code block or a block level statement (such as a for statement or a raw code block)
If the class declares a field with a certain name, then the declaration of that field is said to hide any and all accessible declarations of fields with the same name in superclasses, and superinterfaces of the class.
This prints 1:
int[] a = { 1, 2, 3, 4 };
int[] b = { 2, 3, 1, 0 };
System.out.println( a [ (a = b)[3] ] );
Expression (a=b)[3] is fully evaluated AFTER a[ ...] , so a is always original a just for outside of expression!!!
Finally is always executed before return !!! Finally is always executed before return !!!
an else clause belongs to the INNERMOST if !!!!
ex: this prints nothing when passed 2 string args of "blah1 blah2" :
public static void main(String[] args){
if (args[0].equals("open"))
if (args[1].equals("someone"))
System.out.println("Hello!");
else System.out.println("Go away "+ args[1]);
}
.valueOf returns Wrapper Object; .parse... returns primitive
This will print out 10 !!!!!
Object t = new Integer(106);
int k = ((Integer) t).intValue()/10;
System.out.println(k); // 106/10 = 10 and drops remainder
This will print with remainder 10.6 :
Object s = new Integer(106);
float j = Float.valueOf((Integer)s)/10;
System.out.println(j);// 10.6
System.out.println(3 + 100/10*2-13); // left to right +\- after *
while (false) { x=3; } is a compile-time error because the statement x=3; is not reachable;
exception to this rule, if-statement: if(DEBUG){ System.out.println("beginning task 1"); }
Protected methods are accessible from class B if B extends A AND ALSO new B() was used (rather than new A()). You must have an instance of current class wanting access rather than just merely creating a instance of SuperClass which is not naturally accessible from the sub-class without having a instance of the sub-class.
Widening is preferred to boxing/unboxing: int will be promoted to long before being boxed to Integer.
- probe(Integer) will be bound to probe(Integer) (exact match). If that is not available, it will be bound to probe(long), and then with probe(int...) in that order of preference.
- considering probe(Integer), probe(long) is preferred over probe(int...) because unboxing an Integer gives an int and in pre 1.5 code probe(long) is compatible with an int
- considering probe(Integer), It is never bound to probe(Long ) because Integer and Long are different object types and there is no IS-A relation between them. (This holds true for any two wrapper classes).
- probe(int) is bound to probe(long), else to probe(Integer) - boxing an int qives you an Integer which matches exactly to probe(Integer), and other-else to probe(int...).
- It is never bound to probe(Long) because int is not compatible with Long object.
Remember : variables are SHADOWED and methods are OVERRIDDEN.
- Casting down to a super class will give you access to the shadowed variable (not shadowed method!!!!)
Lambdas can contain Java expressions, not statements.
b + 1 is an expression while a = b + 1; is a statement. A statement consists of expressions.
All the wrapper objects are immutable (like String):
'i++' is the same as 'i = new Integer( i.intValue() + 1);'
To save on memory, Java 'reuses' all the wrapper objects whose values fall in the following ranges:
All Boolean values (true and false)
All Byte values
All Character values from \u0000 to \u007f (i.e. 0 to 127 in decimal)
All Short and Integer values from -128 to 127
So == will always return true when their primitive values are the same and belong to the above list of values. This does not apply on a larger value like 130 or 256.
One catch, however, is that when you create a primitive wrapper using the new keyword, a new object is created and a cached object, even if available, is not used. For example:
Integer i = 10; //Wrapper created without using the new keyword and is, therefore, cached.
Integer j = 10; //Cached object is reused. No new object created.
Integer k = new Integer(10); //New object is created. Cached object is not reused.
This implies that i == j is true but i == k is false.
All local (aka automatic) variables, are not initialized automatically. They have to be initialized explicitly. However, it is ok to leave them uninitialized if you don't use them anywhere in the code.
final variables all need to be initialized by declaration or in constructor/block.
Ternary:
Ternary expressions are statements, not expressions, so dont use them in a lambda.
Thus, a?b:c?d:e?f:g means the same as a?b:(c?d:(e?f:g)).
Example (where .poll() is NOT returning void() ); return val is the expression type of operand 2 or 3:
public Object pop(){
return queue1.isEmpty() ? queue2.poll() : queue1.poll();
}
Concerning (where public void out1(); and public void out2(); ) :
int i = 10;
System.out.println( i<20? out1() : out2() );
Note that it is not permitted for either the second or the third operand expression of the '?' operator to be an invocation of a 'void' method. (Probably because void cannot contribute value to an expression)
- If one of the operands is of type byte and the other is of type short, then the type of the conditional expression is short.
- If one of the operands is of type T where T is byte, short, or char, and the other operand is a constant expression of type int
whose value is representable in type T, then the type of the conditional expression is T.
- If one of the second and third operands is of the null type and the type of the other is a reference type, then the type of the conditional expression is that reference type.
- If the second and third operands are of different reference types, then it must be possible to convert one of the types to the
other type (call this latter type T) by assignment conversion, the type of the conditional expression is T. It is a compile-time error if neither type is
assignment compatible with the other type.
For lambda expressions, 'return;' is the same as 'return null;' where you have an interface like this:
interface Runner {
public void run();
}
- () -> System.out.println("running...")
- () -> { System.out.println("running..."); return; }
synchronized keyword may be applied to a non-primitive variable
synchronized keyword can never be applied to a class; It can only be applied to a method or a block.
The synchronized keyword prevents concurrent access to a block of code or object by multiple Threads. By default, a Hashtable is synchronized, so only one thread can access the table at a time.
On usage of non-synchronized constructs like HashMap,you must build thread safety features in your code to prevent memory consistency errors.
A final variable on a superclass can be hidden in a subclass.
Considering this method:
public void testRefs(String str, StringBuilder sb){
str = str + sb.toString();
sb.append(str);
str = null;
sb = null;
}
The call 'sb = null' only nulls the reference, not the external StringBuilder object that came in. The 'sb.append(str)' actually appends on the StringBuilder object (outside the method) but doesn't return a new stringbuilder and so it doesn't affect the local sb reference.
A class can contain 2 overloaded main methods, thus this is ok:
public class FunWithArgs {
public static void main(String[][] args) {
System.out.println(args[0][1]);
}
public static void main(String[] args) {
FunWithArgs fwa = new FunWithArgs();
String[][] newargs = {args};
fwa.main(newargs);
}
}
'finally' is ALWAYS executed. (Only exception is System.exit() )
If you want to write a value in binary, it must be prefixed with 0b or 0B.
int b = 0b01001110_00100000; // 20,000
hint: 2 to the 14th power = 16,384
public String intern()
Returns a canonical representation for the string object.
It follows that for any two strings s and t, s.intern() == t.intern() is true if and only if s.equals(t) is true.
String does not have a .append method. Only use intern if you want better speed so you can use == to compare strings.
Interfaces are always abstract.
NOT TRUE: In Java 8, interfaces allow multiple implementation inheritance through default methods.
WHY: They don't. You cannot have a class that implements two interfaces where both the interfaces contain a default method with the same signature unless the class provides an implementation for that method itself; therefore we still effectively have single inheritance.
Not all interface methods are implicitly abstract, you can have implemented default and static methods.
Base b=new Sub(); does not mean you can call a method that exists only in Sub, unless it exists in the parent class Base. The super type
reference hides the sub-class method from the b object at compile time. If you cast it back to Sub, then you will have access to Sub methods.
// yes I verified this is true
import java.util.*;
public class Blah {
public static void main(String[] args) {
Set<Short> set = new HashSet<Short>();
for (short i=0; i < 10; i++)
{
set.add(i);
System.out.println("i:"+i);
System.out.println("remove:"+set.remove(i-1)); // cant remove integers from a short list
}
System.out.println("size:"+set.size()); // 10
}
}
Weird, tough to understand:
public static void main(String[] args) {
int i = 1234567890;
System.out.println(i); // 1234567890
float f = i;
System.out.printf("f: %f\n", f); // f: 1234567936.000000 = 1234567890 + 36
System.out.println(i - (int)f); //-46
float fx = (float)i;
System.out.printf("fx: %f\n", fx); // fx: 1234567936.000000
long dx = (long)i;
System.out.println(dx); // 1234567890
System.out.println(i - (long)f); //-46
}
This is because the information was lost during the conversion from type int to type float as values of type float are not precise to nine significant digits. float is 4 bytes; double is 8; long is 8; int is 4.
https://www.h-schmidt.net/FloatConverter/IEEE754.html
This loop is skipped:
int sum = 0;
for (int i = 0, j = 10; sum > 20; ++i, --j) // 1
{
sum = sum+ i + j;
}
No access modifer to age means it has default access i.e. all the members of the package can access it. This breaks encapsulation.
Would work if 'protected int age;'
NOTE: I got this wrong in a practice test but I don't completely understand it; isn't default more restrictive than protected?
A: If a member of a class is declared protected, it is accessible to all classes within the package (the same as the default package accessibility) and also accessible within the body of any subclass of the class, regardless of the package in which that subclass is defined. This is more restrictive than public access, but less restrictive than package access.
Explanation: Because methods can take superclass args, its better for the method to be protected (rather than default) because the superclass may be in a different package.
Generally:
To achieve encapsulation in Java −
- Declare the variables of a class as private.
- Provide public setter and getter methods to modify and view the variables values.
- public static field's are associated with class not with object, it break Object's encapsulation rule.
- protected is better than package-private in cases where method takes superclass type.
Concerning:
class A {
public int getCode(){ return 2;}
}
class AA extends A {
public void doStuff() { }
}
public static void main(String[] args)
{
A a = new AA();
AA aa = (AA) a;
((AA)a).doStuff();
a = (AA)aa;
a = new AA();
//But these are NOT ok:
//aa = a; // compile error: cannot be auto-boxed up
//aa = new A(); // compile error: cannot be autoboxed up
}
This List method returns a boolean:
public boolean remove(Object o)
Unlike sets, lists typically allow duplicate elements.
The List interface places additional stipulations, beyond those specified in the Collection interface, on the contracts of the iterator, add, remove, equals, and hashCode methods.
Strangely, is permissible for lists to contain themselves as elements
Lists usually have RuntimeExceptions, not compile time.
In List, these return void: add, list, sort(Comparable), all others return boolean, int, or something else.
List Example with Lambda:
Predicate<Person> personPredicate = p-> p.getPid() == pid; // where Person object has .getPid() method
list.removeIf(personPredicate);
String[] strArr = new String[5]; will initialize all inner strings to null .
Empty string is not the same as null!
java.lang.Error is not a java.lang.Throwable. Throwables can be used in catch clauses.
This is ok but will also catch Error:
try {
// Some code
} catch(Throwable e) {
// handle the exception
}
Can be confusing: The catch BLOCK itself is meant to handle the exception. The catch is just before the handling block. As a programmer, you can't define your own exception handling since that is what the try-catch accomplishes for you. Instead you can log or print within the catch clause. In a way, wrapping code with a try-catch is an attempted to "handle" errors.
Control flow statements, however, break up the flow of execution by employing decision making, looping, and branching, enabling your program to conditionally execute particular blocks of code.
Equals method of a primitive wrapper class ( e.g. java.lang.Integer, Double, Float etc) are
symmetric => a.equals(b) returns same as b.equals(a)
transitive => if a.equals(b) and b.equals(c) return true, then a.equals(c) returns true.
reflexive => a.equals(a) return true.
The wrapper classes's equals() method overrides Object's equals() method to compare the actual value instead of the reference.
private StringBuilder sb = new StringBuilder();
sb.delete(0, sb.length());
// no such thing as .removeAll(), .clear(), or .deleteAll() for StringBuilder
To clear a StringBuilder: sb.setLength(0);
Its ok to have a local variable with the same name as a class variable. They are references to different objects, unless you use 'this.' to reference the class variable and clarify the ambiguity.
A class invariant is simply a property that holds for all instances of a class, always, no matter what other code does.
For example,
class X {
final Y y = new Y();
}
&& and || do not evaluate the rest of the expression, when first operand is true
|| and && are short circuiting operations
You cannot have break or continue in an 'if' or 'else' block without being inside a loop.
RandomAccess is a marker interface used by List implementations to indicate that they support fast (generally constant time) random access.
You do not need to specify the class of objects you want to store in ArrayList when you declare a variable of type ArrayList. You would only lose compile time type checking.
A boolean cannot be used in a case statement.
Try not to throw RuntimeExceptions explicitly since they are meant for unforseen and unrecoverable exceptional situations. Expect them to be thrown implicitly instead, when an error condition occurs. A Java programmer developing a desktop application would probably explicity throw "Exception" in a method signature. In other words, never explicitly declare a runtime exception in a method signature since it can mislead readers of the API. Notify users in the JavaDoc instead, this allows users of the API to know that they can ignore the exception rather than requiring them to handle it. Having to add runtime exceptions in every method declaration would reduce a program's clarity.
A test class implementing 2 interfaces, each having the same static variable, is ok, but they cant be referenced unless by casting down to one of the interfaces, or by direct access InterfaceA.staticVar .
So, any of the VALUE fields can be accessed by casting.
Surprising, this is ok, and has no problem with local scope. Scope is outside the 'case' keyword. :
switch(Integer.parseInt(args[1]))
{
case 0 :
boolean b = false;
break;
case 1 :
b = true; //2
break;
default:
}
The statement : 'if (false) ; else ;' is OK // if statements dont care about unreachable code
review: http://docs.oracle.com/javase/tutorial/essential/exceptions/
Checked exceptions are subject to the Catch or Specify Requirement. All exceptions are checked exceptions, except for those indicated by Error, RuntimeException, and their subclasses.
catch or specify: https://docs.oracle.com/javase/tutorial/essential/exceptions/catchOrDeclare.html
One case where it is common practice to throw a RuntimeException is when the user calls a method incorrectly. For example, a method can check if one of its arguments is incorrectly null. If an argument is null, the method might throw a NullPointerException, which is an unchecked exception.
Exceptions provide the means to separate the details of what to do when something out of the ordinary happens from the main logic of a program.
Remember that variables and static methods are not overridden and so access to variables and static methods is determined at compile time based on the type of the variable (instead of type of the object referred to by the variable, as is the case with instance methods.)
Static variables in Java are not inherited, they exist only in the class which declares them; however, they can be accessed implicitly by referring to an instance or subclass (or subclass instance) of the class which defines the static variable. (NOTE: static members of interface are not part of class instance)
The JavaDoc description of java.time.temporal.TemporalAdjusters is very helpful.
To print next Tuesdays date:
System.out.println(LocalDate.now().with(TemporalAdjusters.next(DayOfWeek.TUESDAY)));
System.out.println(TemporalAdjusters.next(DayOfWeek.TUESDAY).adjustInto(LocalDate.now()));
Also:
static TemporalAdjuster TWO_DAYS_LATER = TemporalAdjusters.ofDateAdjuster(date -> date.plusDays(2));
Also:
long lastDay = temporal.range(DAY_OF_YEAR).getMaximum();
temporal.with(DAY_OF_YEAR, lastDay);
Remember: LocalDate.adjustInto(LocalDate.now())
= has least precedence of all operators.
Casting rules apply to arrays also:
This returns a double: return (long) by/d*3; // because cast occurs before division by double
ArrayList<Double> al = new ArrayList<>();
System.out.println(al.indexOf(1.0)); // indexOf's accepts Object as a parameter. Although 1.0 is not an object, it will be boxed into a Double object.
al.add(111); // You cannot autobox an int into a Double object (I think you can via cast or assignment; float f = 5; is ok , for example, with risk of loss of precision).
Double d = al.get(al.length); // ArrayList does not have a field named length
float f1 = 1.0; is incorrect ; 1.0 is a double
float f = 43e1; is incorrect; 43e1 is also a double ; e1 implies moving decimal place and so compiler moves decimal place and does it in a double
float f = 0x0123; is ok
Double.parseDouble("9.78313E+2"); // example
0x6400 translates to 6*16^3 + 4*16^2 + 0*16^1 +0*16^0 = 25600
0xB3AD = (11×163) + (3×162) + (10×161) + (13×160), which is 45997 base 10.
Overriding a method that throws a checked exception in the super class, but doesn't throw an exception in the subclass is totally ok. Exception wont be required to be handled any longer since its implied via inheritance.
polymorphism means that it is always the class of the object (and not the class of the reference variable that a variable points to) that determines which method will be called at run time. The concept of polymorphism doesn't apply to private methods or static methods because these methods are never inherited.
You dont call the method via a reference type unless it has an instance!
an overriding method is allowed to change the return type to any subclass of the original return type, also known as covariant return type. This does not apply to primitives, in which case, the return type of the overriding method must match exactly to the return type of the overridden method.
Var defined in try block is not visible in catch block.
Anything bigger than an int can NEVER be assigned to an int or anything smaller than int ( byte, char, or short) without explicit cast.
CONSTANT values up to int can be assigned (without cast) to variables of lesser size ( for example, short to byte) if the value is representable by the variable.( that is, if it fits into the size of the variable).
operands of mathematical operators are ALWAYS promoted to AT LEAST int. (i.e. for byte * byte both bytes will be first promoted to int.) and the return value will be AT LEAST int.
All compound assignment operators internally do an explicit cast.
char c = c + b ; // incorrect c and b are promoted to int and cant be assigned back to char without a cast
int i = c + b; // ok
yes, import static x.y.SM.foo; will work to statically import a method.
FOR: int k = (Integer) t.intValue()/9;
the . operator has more precedence than the cast operator
It is valid for MyHouse to say that it implements Bungalow as well as House even though House is redundant because Bungalow is a House anyway.
Ok, this looks like it will get an out of bounds at index 9, but it wont:
public static void main(String args[]){
int size = 10;
int[] arr = new int[size];
for (int i = 0 ; i < size ; ++i) System.out.println(arr[i]);
for (int i = 0 ; i < size ; i++) System.out.println(arr[i]);
}
The ++i increments after the loops statements are executed, just like i++ does, so, both loops print the same thing
BUT
for (int i = 0 ; i < size ; ) System.out.println(arr[i++]); //now this breaks with out of bounds exception
As per the API documentation for charAt, it throws IndexOutOfBoundsException if you pass an invalid value.
Both - ArrayIndexOutOfBoundsException and StringIndexOutOfBoundsException, extend IndexOutOfBoundsException
The charAt(int ) method can take a char value as an argument because char is promoted to int
In addition to the EventListener classes, Single Abstract Method (SAM) interfaces like Runnable and Comparator are also better represented with a Lambda expression.
NOTE: The following only work if you pretend that there are valid interfaces that can consume these in your code:
(int x, int y) -> x + y
() -> 42
(String s) -> { System.out.println(s); }
Runnable r2 = () -> System.out.println("Hello world two!");
r2.run();
Consumer<Object> c1 = x -> System.out.println(x);
Consumer<Object> c2 = System.out::println;
c1.accept("Print via lambda");
c2.accept("Print via method reference");
Playing card code example: http://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html
# Comparator (where 'public int compare(Person p1, Person p2)' ) #
Comparator<Developer> byName = (Developer o1, Developer o2)->o1.getName().compareTo(o2.getName());
List<Developer> listDevs = ...
listDevs.sort((Developer o1, Developer o2)->o1.getAge()-o2.getAge()); //.sort takes a Comparable as an arg
# Runnable (where 'public void run()' ) #
Runnable r2 = () -> System.out.println("Hello world two!");
On a HashMap, you can do this:
items.forEach( (k,v)->System.out.println("Item : " + k + " Count : " + v) );
The DRY principle is not followed. (DRY=Dont Repeat Yourself) Lambdas help in this case:
-Each method repeats a looping mechanism.
-The selection criteria must be rewritten for each method
Example anonymous class:
public interface MyTest<T> {
public boolean test(T t);
}
Java SE 8 provides the java.util.function package with a number of standard functional interfaces. In this case, the Predicate interface meets our needs.
public interface Predicate<T> {
public boolean test(T t);
}
Lambda expressions solve the vertical problem and allow the easy reuse of any expression, to apply it to a list of objects:
List<Person> pl = Person.createShortList();
Predicate<Person> allDrivers = p -> p.getAge() >= 16;
robo.phoneContacts(pl, allDrivers);
And that is applied like this anonymous class:
robo.phoneContacts(pl,
new MyTest<Person>(){
@Override
public boolean test(Person p){
return p.getAge() >=16;
}
}
);
((Predicate<String>) e -> e.equals("1")).or(e -> e.equals("2"))
is a short circuit or, like this:
e -> e.equals("1") || e.equals("2") // note how the right hand of the arrow token is sharing the e from the left hand side
Advanced, not on exam:
Arrays.asList("1", "2", "3").stream().filter( $(e -> e=="1").or(e -> e=="2") ).count();
java.time.LocalDate is immutable AND thread-safe
A date without a time-zone in the ISO-8601 calendar system, such as 2007-12-03.
This is a value-based class; use of identity-sensitive operations (including reference equality (==), identity hash code, or synchronization) on instances of LocalDate may have unpredictable results and should be avoided. The equals method should be used for comparisons.
LocalDate.atTime returns a LocalDateTime
LocalDate.of
LocalDate.now()
LocalDate.parse
LocalDate.plusDays returns a copy, just like String
Period.ofDays //static, dont chain it
Any two integral primitives can be compared using == operator.
This will not compile because k and i are referring to objects that have no IS-A relationship among themselves.
Short k = 9; Integer i = 9; System.out.println(k == i);
// yes, i verified this is true!!
You know that Number class is abstract super class of some other classes like Integer, Long, Float, BigInteger, and many more.. Now why Java don't allow comparison of two Number instances can be inferred by the fact that - "Any mutable object should not implement Comparable interface, because while the comparison is in process, your object may change".
What makes Number class mutable is two of its subclasses - AtomicInteger and AtomicLong which are used for multi-threading applications and also they are mutable. That makes sense for Number class not to implement Comparable, that will of course force a constraint on AtomicInteger and AtomicLong to implement it.
There is no constructor in Short that takes an int.
Short s = new Short( (short) 9 ); will work.
The left operand of instanceof MUST be an object reference and not a primitive.
Right operand of instanceof MUST be a class name.
Problems with array dimensions will be caught by compiler, not at runtime, like an array that just has an out of bounds index access.
Comparison operators have lower precedence than mathematical operators. \
Therefore, 1 + 5 < 3 + 7 is evaluated as (1 + 5) < (3 + 7) i.e. 6<10, which prints true.
Similarly, (2 + 2) >= 2 + 3 is evaluated as (2 + 2) >= (2 + 3) i.e. 4>=5, which prints false.
This is oK: System.out.println("a"+'b'+63);
StringBuffer .setLength is able to truncate itself, even if the length is set to be longer afterwards.
The Exception that is thrown in the last, such as in the finally block, is the Exception that is thrown by the method to the caller.
You won't see multiple exceptions thrown. (But you can see multiple compile errors thrown)
Exception thrown by a catch cannot be caught by the following catch blocks at the same level. A catch clause cannot throw to another catch clause; there can be only one catch clause!
Boolean class has two constructors - Boolean(String) and Boolean(boolean)
The String constructor allocates a Boolean object representing the value true if the string argument is not null and is equal, ignoring case, to the string "true". Otherwise, allocate a Boolean object representing the value false. Examples: new Boolean("True") produces a Boolean object that represents true. new Boolean("yes") produces a Boolean object that represents false.
Boolean.TRUE or Boolean.FALSE wrapper objects: Observe that they dont create a new Boolean object but just return the static constants TRUE or FALSE defined in Boolean class.
When you use the equality operator ( == ) with booleans, if exactly one of the operands is a Boolean wrapper, it is first unboxed into a boolean primitive and then the two are compared. If both are Boolean wrappers, then their references are compared just like in the case of other objects.
Thus, new Boolean("true") == new Boolean("true") is false, but new Boolean("true") == Boolean.parseBoolean("true") is true.
Even though both the sides have a Boolean wrapper containing true, the expression will yield false because they point to two different Boolean wrapper objects.
Boolean.parseBoolean("TrUe") == new Boolean(null);
This will yield false because parseBoolean("TrUe") will return true and new Boolean(null) will return a Boolean wrapper object containing false.
finally cannot occur before any catch block.
This is ok. for loop does not need a body!
try {
for( ;; );
}finally { }
For all of the methods in String and StringBuilder that take two int parameters for specifying a range, remember that the first index is included but the last index is not.
For example, for a full phone number separated with dashes, the arguments given are 0 and 7, which means it will include the characters with index 0 to 6, that is, a total of 7 characters 0, 1, 2, 3, 4, 5, and 6 :
Remember that String class doesn't have append (and insert) method because a String cannot be mutated. String.concat returns a copy.
Invalid because local var not initialized:
public static void main(String args[ ] )
{
int i, j;
for (j=10; i<j; j--) { i += 2; }
}
You cannot store primitives in an ArrayList. - This is true because only Objects can be stored in it.
ArrayList allows constant time access to all its elements. - This is true because it implements java.util.RandomAccess interface, which is a marker interface that signifies that you can directly access any element of this collection. This also implies that it takes the same amount of time to access any element.
You cannot have unlabeled block of code inside a switch block. Any code block must succeed a case label and colon char (or default: label).
Since the code is using IOException, the java.io package (or just java.io.IOException class) must be imported. Only java.lang package is imported automatically.
import java.io.IOError
Beware, when you see 'throw new XXXError`, no exception clauses are caught. A subclass of Error cannot be caught using a catch block for Exception because java.lang.Error does not extend java.lang.Exception.
This is ok, with a space: while (j < = 5) is the same as while (j <= 5)
Also: 'int[] vars[] = new int[]{1,2}' is the same as 'int [] vars[] = new int[]{1,2}'
A for loop can contain a internal variable (in the for-expression) with the same name as a class variable and it will not conflict.
import java.lang.Math
Math.round(-0.5) = 0.0 // rounds up always
A switch condition cannot accept float, long, double, or boolean.
final only means that subclasses cannot shadow (in case of static methods) or override (in case of instance methods) it.
only static method can hide a superclass static method; an instance method cannot hide a superclass static method
instance methods can override superclass instance methods
For X || B && C , the B and C are never evaluated if X =true. Short circuiting causes evaluation right to left.
The equals method of all wrapper classes first checks if the two object are of same class or not. If not, they immediately return false.
For the following:
Integer i1 = 1;
Integer i2 = new Integer(1);
int i3 = 1;
Byte b1 = 1;
Long g1 = 1L;
i1.equals(i2) // true This will return true because both are Integer objects and both have the value 1. Wrapper class knows how to compare objects of same type via .equals implementation.
i1 == i3 // true This will return true because one operand is a primitive int, so the other will be unboxed and compared.
i1.equals(g1) //false This will return false because they are pointing to objects of different types.
i1.equals(b1) //false This will return false because they are pointing to objects of different types.
i1 == i2 //false This will return false because both are pointing to different objects.
i1 == b1 //false This will not compile because type of i1 and b1 references are classes that are not in the same class hierarchy. So the compiler figures out at compile time itself these two references cannot ever point to the same object.
If the final values of the variables are as follows -
x=2 y=1 z=1 a=1 b=2
The expression x>a?y>b?y:b:x>z?x:z; should be grouped as -
x > a ? (y>b? y : b) : (x>z? x : z);
It will, therefore, assign 2 to answ.
Rewrite with parenthesis to separate into segments of x?y:z . The 2 : chars near each other should be a sign of a wider expression and so the parenthesis needs to separate so that the 2 : chars are not near each other any more.
This terniary expression had 2 right hand expressions evaluating to int .
Yes, local variables can be explicitly declared as final. But, I think this is because they are implicitly final?
For:
class A {}
class B extends A {}
class C extends B {}
Practice these:
(o instanceof B) && (!(o instanceof C))
! ( !(o instanceof B) || (o instanceof C))
(o instanceof B) && !((o instanceof A) || (o instanceof C))
(o instanceof B) && (!(o instanceof A))
!((o instanceof A) || (o instanceof B))
Unshadowing variables works by casting to a superclass/interface (not totally sure about this: but it does not work for methods if the classes are nested more than 1 deep).
You can access only immediate parent class variables with super.methodCall
Yes, a private field is always accessible from within the same class, even from public static void main if the class is self-instantiated into an instance.
String, StringBuilder, and StringBuffer - all are final classes.
Remember that wrapper classes (java.lang.Boolean, java.lang.Integer, java.lang.Long, java.lang.Short etc.) are also final and so they cannot be extended.
java.lang.Number, however, is not final. Integer, Long, Double etc. extend Number.
java.lang.System is final as well.
Yes, a List that you pass to a method is passed by reference. Any objects you add to the List inside the method will still be in the List after the method returns.
A method is said to be overloaded when the other method's name is same and parameters ( either the number or their order) are different.
this( ... ) can only be called in a constructor and that too as a first statement.
Be careful of any question saying "fails at runtime" since you'll be tempted to answer with a compile time problem.
Binary: Java includes a variety of binary operators, such as arithmetic, logical, bitwise, equality, relational, and assignment operators.
Bitwise: an operator that performs a bit comparison between two values. Includes: &, ^, and |.
Compound assignment operator: An assignment operator that first applies a numeric, logical, or shift operation to a value before assigning it to a variable. Includes =, +=, -=, *=, /=, %=, &=, ^=, |=, <<=, >>=, and >>>=.
Conditional operator: The operator a ? b : c, where a is a boolean expression, b is the expression when a is evaluated to true, and c is the expression when a is evaluated to false.
Inner classes have only protected or private as modifiers, not public or default.
Nested classes that are declared static are called static nested classes. Non-static nested classes are called inner classes.
What is the purpose of using the default package private modifier? Many classes are defined within the same Java file.
Object fooHolder = (Foo1) () -> System.out.println("Hello");
System.out.println(fooHolder instanceof Foo1); // returns true only if Foo1 is a functional interface
Example of how a lambda looks different:
Foo2 longFoo = new Foo2() {
@Override
public int bar(boolean baz) {
return baz ? 1 : 0;
}
};
Foo2 shortFoo = (x) -> { return x ? 1 : 0; };
These are equivilant:
IntUnaryOperator addOneShort = (x) -> (x + 1);
IntUnaryOperator addOneLong = (x) -> { return (x + 1); };
Example having scoped variable:
IntUnaryOperator makeAdder(int amount) {
return (x) -> (x + amount); // Legal even though amount will go out of scope
// because amount is not modified
}
IntUnaryOperator makeAccumulator(int value) {
return (x) -> { value += x; return value; }; // Will not compile
}
for (int i = 0; i < n; i++) {
new Thread(() -> System.out.println(i)).start();
// Error—cannot capture i
}
this is not legal because i changes. There is no single value to capture. The rule is that a lambda expression can only access local variables from an enclosing scope that are effectively final.
int first = 0;
Comparator<String> comp = (first, second) -> first.length() - second.length(); // Error: Variable first already defined
Wont compile:
public class HelloWorld
{
public static void main(String[] args)
{
int x = 0;
do
test();
x++;
while (x < 4); // error: not a statement
}
static void test() {
System.out.println("Test");
}
}
int[] is = new int[]{1,2,3};
String[] ss = (String[])is; // error: incompatible types: int[] cannot be converted to String[]
Predicate<String> takes a parameter list of one parameter using the specified type.
IN a lambda, the arg to the left of the arrow must match the name of the arg operating upon on the right side.
A method, throwing a optionally handled Runtime exception, not wrapped in a try block, will just throw out the runtime exception automatically and code will stop.
With Collections.sort(), uppercase letters sort before the lower case ones.
This is ok:
import java.io.*;
try{
throw new IOException();
} catch (IOException e) {
throw e;
}
default access modifier is more restrictive than protected and so you cant do that when overriding a method that is protected in the superclass.
All String literals are automatically instantiated into a String object.
StringBuilder and StringBuffer define the exact same public methods.
Customized interface that operates like Predicate<Boolean> :
interface Climb {
boolean isTooHigh(int height, int limit);
}
public class Climber {
public static void main(String[] args)
{
check((h,l) -> h>l, 5);
}
private static void check(Climb climb, int height)
{
if (climb.isTooHigh(height, 10))
System.out.println("too high");
else
System.out.println("ok");
}
}
Learn the constructors of Period and LocalDate better.
Constructors dont have return types!!!!
Always check if an question is multiple choice or not.
All objects in Java are accessed via a reference.
The type of the object determines which properties exist within the object in memory.
The type of the reference to the object determines which methods and variables are accessible to the Java program.
This prints 3 lines of stack trace Exception following AC . e.printStackTrace just gives you more verbose output:
public class ColorPicker {
public void pickColor(){
try{
System.out.println("A");
fail();
} catch (NullPointerException e) {
System.out.println("B");
} finally {
System.out.println("C");
}
}
public void fail()
{
throw new ArithmeticException();
}
public static void main(String[] args){
new ColorPicker().pickColor();
System.out.println("D");
}
}
Does not compile:
char x = 'x';
String answer = x;
The default access modifer of interface methods is "public", even if you wrote no-modifier/default access. So, be careful
when implemeting the methods because you wont be able to use default access.
Anonymous array initialization is ONLY allowed in declaration. So, dont try this:
String[] grades; grades = {"A", "B"};
Interfaces can have abstract methods just like abstract classes. In a interface, the abstract modifier is useless/does-nothing .
Be careful, when using ArrayList and List, imports are needed: java.util.ArrayList and java.util.List
When using += operator, left hand var must be previously declared.
If you cast an Object to a class-type, you probably wont see the error until Runtime, not compile time.
Bare initializer blocks will be called before Constructor but ALSO after super() is called at the beginning of a constructor. This is tricksy. In case of top-level class, super() constructs Object, and then it appears bare-initializer is called before any other lines in constructor, then, in the sub-class, after super() was called, the bare-initializer is called and then the remaining constructor code.
Exceptions Example:
public class HelloWorld {
public static void main(String... args) {
System.out.println(exceptions());
}
public static String exceptions() {
String result = "";
String v = null;
try {
try {
result += "before ";
v.length();
result += "after ";
} catch (NullPointerException e) {
result += "catch ";
throw new RuntimeException("runtime ");
} finally {
result += "finally ";
throw new Exception("finally ");
}
} catch (Exception e ){
result += "done ";
e.printStackTrace();
}
return result;
}
}
OUTPUT:
java.lang.Exception: finally
at HelloWorld.exceptions(HelloWorld.java:18)
at HelloWorld.main(HelloWorld.java:3)
before catch finally done
Reference Types:
public class Java8_I {
static class RefType {
int val;
RefType(int val) {this.val = val;}
}
public static void main (String[] args) {
RefType x = new RefType(1);
modifyVar(x);
x.val = x.val + 5;
System.out.println("x: " + x.val);
}
public static void modifyVar(RefType var) {
var.val = 10;
}
}
Variables of reference types hold references to object instances. When var is assigned to x in the modifyVar method, var now references the same object referenced by x. Thus, changing the val field for var will affect x, because all both variables reference the same object. The val field is initialized to 1, then reassigned to 10 and incremented by 5 after returning from the modifyVar method. The final value for the val field is 15.
- Reference type variables in Java are classes and include: int[], String[], Random etc.
- The key difference between primitive variables and reference variables are:
-- Reference variables are used to store "references" or addresses of other variables. Primitive variables store actual values. Reference variables can only store a reference to a variable of the same class or a sub class. These are also referred to in programming as "pointers".
-- Reference types can be assigned null but primitive types can not.
-- Primitive types cannot make method calls but reference types can because they reference an object of a class which may contain methods.
public class Java8_I {
public static void main (String[] args) {
int i = 1;
System.out.println((3 + i) * 6 ^ 2);
}
}
The result is the output 26. Although multiplicative operators normally occur before additive operators, the parentheses in this case will ensure the expression 3 + i is evaluated as 4 first. Because multiplicative operators occur before bitwise operators, the expression 4 * 6 is evaluated as 24 next. The exclusive OR operator (^) compares the binary notation of two numbers, returning a 1 where the numbers have a different value in that position. The decimal 24 is represented in binary as 11000 and 2 as 00010. The result of the exclusive OR operation is 11010, or 26 in decimal notation.
To work with Java's date and time classes you first need to import the java.time* classes into your program. These contain classes for all date-time processing. It has several subpackages:
java.time.chrono, java.time.format, java.time.temporal, and java.time.zone.
public class VarScope {
int i1;
public static void main (String[] args) {
VarScope scope = new VarScope();
scope.printVar();
int i2 = i1; //compile fails!
int i3 = i2;
}
private void printVar() {
System.out.println(i1);
}
}
the instance variable i1 is not available to the static main method. Non-static members cannot be referenced from a static context.
Wont compile since interface-reference (ref-type) needs to include a accessor for the .toString(String) method, otherwise method is not accessible in context :
interface StringInterface {
public String toString();
}
public class SuperString implements StringInterface {
public String toString() {
return "Super String 1";
}
public String toString(String str) {
return "Super String 2";
}
}
class SubString extends SuperString {
public String toString() {
return "Sub String 1";
}
public String toString(String str) {
return "Sub String 2";
}
public static void main(String[] args) {
StringInterface string = new SubString();
System.out.println(string.toString("test")); // the problem is here
}
}
1. public class Java8_I {
2. public static void main (String[] args) {
3. char[] src =
4. { 'j', 'e', 's', 'p', 'r', 'e', 's',
5. 's', 'o', 'a', 'v', 'a', '7' };
6. char[] dest = new char[8];
7. System.arraycopy(src, 1, dest, 0, 8);
8. System.out.println(new String(dest));
9. }
10. }
You can copy array using Java's System class and its arraycopy() method:
public static void arraycopy(source, int sourcepos, destination, int destinpos, int length)
This copies the contents of the source array starting from the source position (sourcepos) to the destination array at the destination position (destnpos) up a specified length.
After the exception handler is executed in the catch block, the system executes code in the finally block. Even if there is no exception thrown, the code in the finally block will be executed.
An array's dimension must be set using the new keyword. The dimension should be declared in the second pair of square brackets that proceed the new keyword.
int[] intArray = new int [10]; //ok
int[] intArray = [0,10,20,30,40,50,60,70,80,90]; //ok
String[] strArray; //preferred
String strArray[]; //not encouraged
The compiler will accept either style to declare an array without specifying a dimension.
Primitive data types, when passed as parameters to methods in Java, are passed by value. This means any changes to the values of the arguments INSIDE the method does not change the values of the variables OUTSIDE the method.
When reference variables are passed to methods, the method could change the members of the object referenced by the variable, provided the method has access to them. The reference variable simply points to an area of memory that stores the actual object.
The covariant return type specifies that the return type may vary in the same direction as the subclass.
NOTE: Before Java5, it was not possible to override any method by changing the return type. But now, since Java5, it is possible to override method by changing the return type if subclass overrides any method whose return type is Non-Primitive but it changes its return type to subclass type.
public class ExceptionFun {
public ExceptionFun(Object obj) {
if (obj == null)
throw new IllegalArgumentException("Provide an object!"); // this prints out AFTER the finally block
System.out.println(obj + " created!");
}
public static void createObject() {
try {
ExceptionFun obj = new ExceptionFun(null);
} finally {
System.out.println("Was the object created?");
}
}
public static void main(String[] args) {
createObject();
}
}
NOTE: this confused me since the finally block didnt actually "throw" anything. But, I guess even though there is not a catch clause, the exception is still thrown.
The result is an exception thrown at run time. IllegalArgumentException is thrown at run time because neither the createObject nor the main method will catch the exception. The constructor is invoked with a null argument, which will throw an IllegalArgumentException. Invokers can either catch or specify the exception. The exception is "thrown up the call stack until it reaches the JVM". The JVM will then shut down the process. This happens even if we dont print or re-throw the stack trace.
A "specified exception" is when you re-throw a caught exception with a new Exception type + with a message.
Valid varargs invocation can have zero arguments. varargs allows an arbitrary number of arguments of the same data type to be specified during invocation. Invocation can include zero or more arguments.
The compareTo method returns 0 for equality. The compareTo method returns a positive integer if the specified String object comes before the String instance and returns a negative integer if the specified String object comes after the String instance
compareTo returns 0 exactly when the equals(Object) method would return true
The following examples illustrate the concept of Java inheritance:
- A method in one class can reuse methods in another class (inherited by extension).
- A method is invoked based on the instantiated object.
A method in one class cannot reuse methods in multiple other classes, because Java does not support multiple inheritances. A subclass can extend only one superclass.
A method invoked based on the method signature is not a concept related to inheritance, but to overloading.
A method is not invoked based on the object reference. The object reference determines which members are accessible, while the version of the invoked method is determined by the instantiated object itself.
Some of the key benefits of using inheritance in Java are:
- Real world parallelism: Inheritance helps better describe real world objects and entities where things are part of a bigger class of things; for example, mortgages, car payments, and education loans are all different kinds of loans.
- Code reuse: You can inherit from an existing class and use its exposed methods in your own code without having to implement those methods yourself.
- Flexibility: By deriving several subclasses from a parent class, you can fine-tune your requirements by implementing subclasses that use specific members of the parent class.
If an exception is thrown in a try block, the code will not continue its normal execution. Execution will move into an associated catch block that matches the exception and/or move into a finally block if associated with the try block.
If an exception is specified, then the exception will be propagated up the call stack. Invokers of the method must either catch or specify the exception until it reaches the JVM. The JVM will shut down the process.
If an exception is caught, then that exception is not propagated down the call stack. Catching an exception allows execution to continue execution outside of its associated try block. This will not stop the program and the program will continue down the stack. Propagation of exceptions occurs up the call stack, not down the call stack.
public class SuperEmptyClass {
public SuperEmptyClass (Object obj) { /*Implementation omitted*/ }
}
public class EmptyClass extends SuperEmptyClass { }
Here, the compiler will provide this constructor for EmptyClass: public EmptyClass() { super();}
This will fail to compile though since SuperEmptyClass has no default constructor.
Yes, Throwable is technically a "Exception class"
The exception classes Throwable and Exception and their subclass ClassNotFoundException are checked by the compiler. Checked exceptions include any exceptions, except for RuntimeException, and its subclasses.
in practice 'throws Throwable' and 'throws Exception' are equivalent.
Yes, you can overload a instance method with another static method.
Missing checked exception handle will cause compile error.
public class CoffeeTest1{
enum CoffeeSize { BIG, HUGE, OVERWHELMING }; // <-- semicolon is optional here
}
int i = 0;
for (;;) {
i++;
}
System.out.println(i);
Compile failure: unreachable code
The object type does not determine which hidden members are accessible. If a member is hidden, rather than overridden, then polymorphism does not apply. The reference type, NOT the instantiated class, determines the accessibility of both hidden and non-hidden members.
Inheritance actually increases coupling between classes, so class decoupling is not a benefit. Decoupling is a benefit of using interfaces, rather than of using inheritance.
public class Java8_I {
static class RefType {
int val;
RefType(int val) {this.val = val;}
}
public static void main (String[] args) {
RefType x = new RefType(1);
RefType y = x;
RefType z = y;
z.val = 10;
System.out.format("x,y,z: %d,%d,%d", x.val, y.val, z.val);
}
}
OUTPUT:
x,y,z: 10,10,10
Variables of reference types hold references to object instances. When y is assigned to x, y now references the same object referenced by x. When z is assigned to y, z now references the same object referenced by y. Thus, changing the val field for z will affect x and y, because all three variables reference the same object.
Reference type variables in Java are classes and include: int[], String[], Random etc.
public class Java8_I {
public static void main (String[] args) {
int[10] intArray; //compile error
intArray[0] = 10;
intArray[10] = 0;
System.out.print(intArray.length);
}
}
All Exception objects, EXCLUDING RuntimeException objects, must be caught or specified for method code to compile. For method code to compile, invocation of methods that specify a checked exception requires catching or specifying that exception. Checked exceptions include any exceptions, except for Error, RuntimeException and their subclasses. Checked exceptions are abnormal conditions internal to the application and often are recoverable.
Runtime exceptions are exceptions that occur due to a code fault and show themselves only at runtime.
Which constructor is the default constructor?
public class CardDeck {
public CardDeck() {/*Implementation omitted*/}
public CardDeck (int suits) {/*Implementation omitted*/}
public CardDeck (int suits, boolean includeJokers) {/*Implementation omitted*/}
}
A: Not provided.
The keyword static indicates a class member. This is the only keyword required for declaring a method as a class member.
GIVEN the following:
interface Climb{
boolean isTooHigh(int height, int limit);
}
public class Climber {
public static void main (Strin[] args) // error: cannot find symbol
{
check((h,l) -> h > l, 5);
}
private static void check(Climb climb, int height) {
if (climb.isTooHigh(height, "max")) // error: incompatible types: String cannot be converted to int
System.out.println("too high");
else
System.out.println("ok");
}
}
COMPILER ERROR at main method occurs BEFORE the compiler error at climb.isTooHigh call
StringBuilder does NOT implement a .equals method.
Don't fall for System.out.println(arrayName[0,0]); // not valid index accessor!
Example of private access:
public class HelloWorld extends HelloExtender
{
public int a = 6;
private int b = 5;
public static void main(String args[])
{
HelloWorld hw = new HelloWorld();
System.out.println( hw.a + hw.b ); // 11
//System.out.println( hw.t ); //error: t has private access in HelloExtender
System.out.println( hw.s ); // 6
System.out.println( hw.b ); // 5
Hello h = new Hello();
System.out.println( h.s + h.i ); // 7
System.out.println( h.t );
//System.out.println( h.j ); //error: j has private access in Hello
}
}
class Hello extends HelloExtender {
public int i = 1;
private int j = 2;
protected int t = 9; // 9 - var hiding
}
class HelloExtender {
public int s = 6;
private int t = 5;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment