0% found this document useful (0 votes)
44 views45 pages

Hot Coffee

Uploaded by

arvinlocal
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
44 views45 pages

Hot Coffee

Uploaded by

arvinlocal
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 45

HOT COFFEE

A R I H A R A S U D H A N
✽ TYPE INFERENCE VAR
In older versions of Java, every variable
must have an appropriate type, every
expression must have an appropriate
type, and every type is strictly defined.
Secondly, all assignments, whether explicit
or via parameter passing in method calls,
are checked for type compatibility. There
are no automatic coercions or conversions
of conflicting types as in some languages.
The Java compiler checks all expressions
and parameters to ensure that the types
are compatible. Any type mismatches are
errors that must be corrected before the
compiler will finish compiling the class.
But, in recent version, we have the so
called Type Inference of Local Variables.
The keyword is var.
To use local variable type inference, the
variable must be declared with var as the
type and it must include an initializer.
> Context Sensitive Identifier
The identifier, var is context sensitive. If we
use this for declaring a type inferenced
variable, yes it will do type inferencing...
But, if we use it as a variable name, it will
be a variable.
We can assign values to var the variable
(in variable context).

Can other types be context sensitive?


Can we assign some value to int,
considering it as variable? NO CHANCE!

ERROR: NOT A STATEMENT


Let’s play with var. The following codes run
smoothly without error.
var cannot be used as the name of a class.
It also cannot be used as the name of
other reference types, including an
interface, enumeration, or annotation, or
as the name of a generic type parameter.
> On Arrays
We can declare an array using var. But, we
can’t have brackets in left side.

Remember, we can’t have brackets. We


infer the type from the intializer (RIGHT
SIDE). Following declarations are not
correct.
> Initialize Please...
Initialize a variable if declared with var.
Don’t stop with declaring. var x = 10; is
correct, meanwhile var y; is not.
> In The Loop
Local variable type inference can be used
in a for loop when declaring and
initializing the loop control variable inside
a traditional for loop.
And also when specifying the iteration
variable in a for-each for:

Meanwhile, We can’t do compound


declaration (in loop) using var. The
following snippet causes ERROR: ‘var' is
not allowed in a compound declaration.
> RESTRICTIONS
> Compound Declaration is not supported.
var x = 2, y = 3, z = 4; is wrong.
> It is not possible to hold null initializer.
var z = null; is wrong.
> Plus, we can’t have an array initializer.
var arr = { 1, 2, 3 }; is wrong.
> It can’t be used to declare the exception
type caught by a catch statement.
> Also, neither lambda expressions nor
method references can be used as
initializers.
> It can’t be used for fields. i.e., it can’t be
used for class level variable declaration. If
you were to use var for fields, it would
introduce ambiguity because the compiler
wouldn't know the type of it until
runtime. This goes against Java's design
principles of static typing and strong type-
checking, which are aimed at catching
errors at compile time rather than
runtime.
✽ SWITCH EXPRESSION
Until Java 7: Only integers could be used
in switch case and this had been the
standard for a long time.
Java 8: Strings and enum were introduced
in case values
Java 12: Enhanced the switch statement
and introduced switch expressions as a
preview feature. New Features were:
Returning values from switch block,
Multiple values in case label, Returning
values from switch expression using break
keyword.
We can also use Arrow to return values.

We can have multiple labels in single case.

Previously, it was like the one given in the


following:
case “MATCH1”:
case “MATCH2”:
return “SOME”;
break;
Java 13: The break keyword was replaced
by yield.
Java 14: Just made all features permanent
from being a preview feature.
Java 17: Provides new features for switch
expression such as,
(1) Pattern matching

The passed object is checked for the type


“Integer” and then assigned to the
variable “i” if it is an integer.
And through the arrow operator the string
“It is an integer” is returned.

(2) Guarded Pattern


If we want to check conditions inside cases
traditionally, we can do the following.
The Guarded Pattern makes it even more
easier...

(3) Null Case


We could never pass a null value to switch
statements prior to Java 17 without a Null
pointer exception being thrown. Java 17
allows us to handle it easily!
Let’s switch to next topic!!!!

The output: “ARI”


✽ JSHELL
The Java Shell tool (JShell) is an interactive
tool for learning the Java programming
language and prototyping Java code. JShell
is a Read-Evaluate-Print Loop (REPL),
which evaluates declarations, statements,
and expressions as they are entered and
immediately shows the results. The tool is
run from the command line. Using JShell,
We can enter program elements one at a
time, immediately see the result, and
make adjustments as needed. JShell helps
us try out code and easily explore options
as we develop our program. We can test
individual statements, try out different
variations of a method, and experiment
with unfamiliar APIs within the JShell
session.
To start JShell, enter the jshell command
on the command line. JDK 9 or higher
must be installed on our system. If your
path doesn’t include the bin directory, for
example java-home/jdk-9/bin, then start
the tool from within that directory.

To exit,
Variable:

A simple function:
Changing Definitions / Redefinitions:

Incompatible Redefinitions:
Commands: Commands are distinguished
from snippets by a leading forward slash
(/). For information about the current
variables, methods, and types, use the
/vars, /methods, and /types
commands. For a list of entered snippets,
use the /list command.
✽ LAMBDA SIMPLIFIED
Java has the so called Lambda Expression.

Output: 2 4 6
Lambda expressions can be stored in a
function using Consumer Interface.
IntBinaryOperator
This is a functional interface and can
therefore be used as the assignment
target for a lambda expression or method
reference. It has a method, applyAsInt
which accepts two integer parameters and
return one integer.
Similarly, we have IntUnaryOperator which
takes an int argument and returns an int
value (e.g., x -> x * 2). Like these 2, we
have for long, double too

> LongUnaryOperator

> LongBinaryOperator

> DoubleUnaryOperator

> DoubleBinaryOperator

How would they have implemented? :-)


✽ SEALED CLASSES
Sealed classes and interfaces restrict
which other classes or interfaces may
extend or implement them. By sealing a
class, we can specify which classes are
permitted to extend it and prevent any
other arbitrary class from doing so.

The code defines the following three


permitted subclasses, Circle, Square,
and Rectangle, in the same module or in
the same package as the sealed class.
SOME MODIFIERS
> final: Cannot be extended further
> sealed: It can only be extended by
permitted subclasses
> non-sealed: It can be extended by
unknown subclasses
Why should we explicitly specify non-
sealed? By default, a class is extendable by
any unknown classes. What is the use of
specifying non-sealed? PEACE
✽ INSTANCE OF WHOM
“instanceof" is a keyword used to test
whether an object is an instance of a
particular class or interface.
ssss

> The instanceof result will be true if


the object is an instance of the type:

All classes are instances of Object Class.


> It will also be true if the object is an
instance of a subclass of the type:
> If the type is an interface, it will
return true if the object implements the
interface:
If we use the instanceof operator on any
object that’s null, it returns false. We also
don’t need a null check when using an
instanceof operator.

PATTERN MATCHING FOR INSTANCEOF


We have pattern matching for instanceof
operator in the latest version of Java (14).
✽ TEXT BLOCKS : Text Blocks
feature is available in Java 15 and it is
used to declare multi-line strings most
efficiently.We don’t need to use multiple +,
newline characters, tabs. We can simply
text block the string.
We will get the output as we provided the
input.

We can also escape!


Inside text blocks, double-quotes don’t
need to be escaped. We could even use
three double-quotes again in our text
block by escaping one of them as shown
in the code above. It is possible with text
blocks to format strings.
✽ “HELPFUL” Null Pointer Exception
A couple of scenarios where the so-called
Null Pointer Exception could be invoked:

“Calling the instance method of a null


object | Accessing or modifying the field
of a null object | Taking the length of null
as if it were an array | Accessing or
modifying the slots of null as if it were an
array | Throwing null as if it were a
Throwable value”
A typical NullPointerException would look
like the following:
Exception in thread "main" java.lang.NullPointerException

at NullPointerExample.printFirstElement(NullPointerExample.java:6)

at NullPointerExample.main(NullPointerExample.java:11)

If the codebase becomes complex, it may


be tedious to find the root-cause of The
NullPointerException. So, let The Helpful
NullPointerException be introduced....

It is really helpful!!! Look at the following


one too...
Exception in thread "main" java.lang.NullPointerException:
Cannot invoke "String.toLowerCase()" because the return value of
"com.baeldung.java14.npe.HelpfulNullPointerException$PersonalDe
tails.getEmailAddress()" is null at
com.baeldung.java14.npe.HelpfulNullPointerException.main(Helpful
NullPointerException.java:10)
✽ NON-VERBOSE COLLECTION
The term "unmodifiable" refers to an
object that cannot be changed after it has
been created.

In our example, the set object is initially


created as a HashSet and populated with
three strings: "foo", "bar", and "baz".
However, after that, it's wrapped in an
unmodifiable wrapper using
Collections.unmodifiableSet(set). This
means that any attempt to modify this set
(like adding, removing, or updating
elements) after the unmodifiableSet()
method is called will result in an
UnsupportedOperationException being
thrown.

Exception in thread "main" java.lang.UnsupportedOperation


Exception at
java.basejava.util.Collections$UnmodifiableCollection.remove(C
ollections.java:1094) at MyClass.main(MyClass.java:10)
Essentially, making a collection
unmodifiable ensures that its contents
remain constant, providing immutability.
The problem is the verbosity in creating a
collection. However, for List, there’s a
factory method:
Luckily, There is a way called Double Brace
Intialization that slightly reduces the
verbosity.

Another way is, using streams:

But, this should be reduced... Do you guys


know Python? :-)

So, what is to reduce this inseparable


verbosity???
None of the above approaches treat the
specific use case creating a small
unmodifiable Collection.

Don’t worry! We can surely reduce this


verbosity in Java 9! Static Methods [of()]
are provided for these interfaces which
take values and returns respective
instances.
We can use them as:

Legends say, it’s still verbose! Those


factory methods look like the following:

There are actually 12 overloaded versions


of this method – eleven with 0 to 10
parameters and one with var-args. Why do
we need these all?
The reason is performance. If we solely
rely on var-args, we have to consider how
it works. Every var-args method call
implicitly creates an array to hold the
passed values. Avoiding unnecessary
object creation is essential. For Maps,
MERCI

You might also like