- Java Fundamentals
- The History and Philosophy of Java
- created at Sun Microsystems to be a platform-independent language
- originally targeted for embedded consumer electronics
- blew up due to the world wide web
- internet populated with many types of computers, operating systems, and CPUs
- adopted syntax from C and object model from C++
- Java simplified internet programming and addressed portability and security
- security by confining application to Java execution environment preventing it from accessing other parts of the computer
- a key part is the bytecode which is executed by the JVM (Java Virtual Machine) which is part of the JRE (Java Runtime Environment)
- All JREs understand the same Java bytecode
- While Java was designed as an interpreted language, supports on-to-fly compilation of bytecode to native code
- java has been moving to a quicker time-based (6-months) release cycle
- Object-Oriented Programming
- OOP is central to language
- OOP grew as a way to help programmers manage complexity
- organize programs around data “data controlling access to code”
- encapsulation
- binds code and data (black box)
- the basic unit is a class in Java
- typically public parts which provide a controlled interface
- polymorphism
- allows one interface to access a general class of actions
- “one interface multiple methods”
- inheritance
- allows an object to acquire properties of another object
- hierarchical classification
- without using hierarchies, each object would have to explicitly define all of its characteristics
- Handling Syntax Errors
- highlighted by compiler
- the error may not always reflect the actual cause of the problem
- Another Data Type
- int represents whole numbers
- also can use float or double (more common) to represent partial numbers
- different types allow for efficient programs
- by choosing different types, Java allows you to make best use of system resources
- Two Control Statements
- if statement helps determine program execution “if(condition) statement”
- for loops allows for repeated execution of code “for(initialization; condition; iteration) statement”
- Create Blocks of Code
- enclosed by opening and closing braces “{}”
- statements inside a block form a logical unit
- Semicolons and Positioning
- semicolons act as separators
- Java does not recognize the end of the line as a terminator
- Indentation Practices
- java is free-form so indentation is not required, but is recommended to do so for readability
- The Java Keywords
- There are 61 keywords which are reserved
- Identifies in Java
- names of methods, variables, or other user-defined items
- can not start with digits
- The Java Class Libraries
- Java is the language itself plus the standard classes
- part of becoming a Java programmer is learning how to use them
- Introducing Data Types and Operators
- Why Data Types are Important
- strong type checking helps prevent errors and enhances readability
- Java’s Primitive Types
- data types
- boolean: true/false
- byte: 8-bit int
- char: Character
- double: double-precision floating point
- float: single-precision floating point
- int: Integer (32-bits)
- long: long integer (64-bits)
- short: short integer (16-bits)
- java specifies strict ranges which all JVMs must support
- allows programs to be fully portable
- Integers
- byte, short, int, long
- no unsigned ints in java
- Floating-Point Types
- floats are 32 bits and doubles are 64 bits
- double more commonly used
- Characters
- 16-bit type unicode
- can increment or add like ints
- Boolean
- Literals
- fixed values that are represented in their human-readable form
- char are single quotes e.g. ‘C’
- ints are numbers without fractional components. e.g. 3
- floating-point has decimal points e.g. 3.3 (defaults to double)
- floating-point with float type 3.3F
- underscores allowed for numbers (e.g. 444_444) which can be useful for part numbers, customer ids, etc
- Hexadecimal, Octal, and Binary
- hexadecimal: 0X prefix
- octal begins with zero
- binary begins with 0B
- Character escape sequences
- can embed in strings e.g. “A\nB”
- A Closer Look at Variables
- variable types cannot change during its lifetime
- all variables must be declared prior to use
- The Scope and Lifetime of Variables
- variables can be declared within any block
- a block defines a scope
- variables defined inside scope not visible outside it
- variables are created when the scope is entered and destroyed when left
- no variable declared within an inner scope can have the same name as a variable declared by an enclosing scope
- Operators
- perform specific mathematical or logical manipulation
- careful when using ints e.g. divide will truncate the remainder
- prefix increment applies increment and returns value while postfix returns value first then increments
- Relational and Logical Operators
- ==, !=, >, <, >=, <=
- &, |, ^, || (short-circuit), && (short-circuit), !
- Assignment Operator
- yields value on the right-hand
- allows “x = y = z = 100” to work
- Shorthand Assignments
- e.g. x += 10;
- can be used with arithmetic and logical operators
- Type Conversion in Assignments
- when compatible types are mixed the right side is automatically converted to the type on the left
- types must be compatible and the destination type must be larger than the source type
- e.g. assigning int to a float type
- Casting Incompatible Types
- form of “(target-type) expression”
- when casting involves a narrowing conversion, information might be lost e.g. going from long to short
- Expressions
- can mix different data types
- different types can be converted to the same type
- char, byte, and short are promoted to int
- if one operand is a long, the whole expression is promoted to a long
- if one operand is a float, the whole expression promoted to a float
- if any operand is a double, whole expression promoted to a double
- can result in unexpected results e.g. operating on two bytes can result in an int type
- Spacing and Parentheses
- use spaces to help with readability
- parentheses can be used to increase the precedence of operations
- Program Control Statements
- Input Characters from Keyboard
- read character from System.in.read()
- by default input is line-buffered
- helps make our program more dynamic
- if statement
- for nested ifs, else statement always refers to the nearest if statement that is within the same block
- if-else-if ladders are evaluated top-down and execute when there is a match
- switch statements
- provides multiway branch
- needs to break after each case or else will run other cases
- can nest switches and use the same case constants
- for loops
- can increment multiple variables
- can leave out initialization, condition or iteration sections
- can declare control variables inside the loop e.g. for(int i = 0;;) to keep it only in that scope
- while loops keep running until a condition is false
- do-while loop: when needs to execute at least once
- break
- can be used to exit the most immediate loop
- can add labels to specify which block to exit but must be the label associated with enclosing block
- continue
- goes to the next iteration of the for loop
- can also use labels here
- can nest for loops
- Introducing Classes, Objects, and Methods
- Class Fundamentals
- class is a template that defines the form of an object
- specifies data and code that will operate on that data
- objects are physical instances of the class
- methods and variables called members
- data members are called instance variables
- a class should group logically connected information
- objects have their own copy of the instance variables
- How objects are Created
- variables for objects hold a reference to them
- new operator dynamically allocates memory for an object and returns the reference
- Reference Variables and Assignment
- for primitive types, variables receive a copy of the value
- for objects, they receive a reference
- Methods
- can use instance variable names without dot operator
- this is implicit
- return to exit if void return a value otherwise
- parameters
- pass in arguments
- passed in arguments are parameters of the method
- Constructors
- default exists for all classes, sets instance variables to null, false, 0
- define by using name of class and can pass in parameters to initialize instance variables
- new operator
- can fail if not able to allocate memory
- garbage collection
- recovers free memory
- does it when there is no reference to an object and there is a reason to recycle
- this keyword
- refers to the object
- is implicit by default
- maybe useful to use if the method parameter has the same name as an instance variable
- by default, the local name hides the instance variable
- can unhide by using this
- More Data Types and Operators
- Arrays
- can have more than one dimensions
- easily manipulated
- arrays are objects
- multidimensional arrays represented with additional brackets e.g. int[][] or int[][][]
- nested arrays can have different lengths for inner arrays
- “int counter[]” and “int counter[]” are both valid and common
- For-Each Style Loop
- can cycle through the array with “for (num: nums)” syntax
- don’t need to initialize, increment, track termination or boundaries
- can exit with break
- can not change contents of the array by assigning the iteration variable a new value
- Strings
- array of characters
- Strings are also objects
- string literals created and reused
- contents of strings are immutable
- can be used in switch statements after java 7
- Command-Line Arguments
- Type Inference with Local Variables
- can only be used for local variables not instance variables, parameters, return type
- don’t have to specify type if the variable is initialized
- var avg = 10;
- useful for user-defined classes
- can use in for loop “for (var x: arr)”
- only one can be declared at a time and cannot use null as the initializer
- only available after Java 10
- be careful about reducing readability
- Bitwise Operators
- &, |, ^, >>, <<, >>>, ~
- can be used on long, int, short, char, or byte
- useful for bit manipulation, masks, etc
- The ? Operator
- ternary
- condition? if-true : if-false
- A Closer Look at Methods and Classes
- Controlling Access to Class Members
- default access is public
- prepend members with “private” to make only accessible in within class
- “protected” used in inheritance
- helps with encapsulation and keeping internals hidden
- can force invariants with access methods
- Pass Objects to Methods
- primitive types passed by value
- objects types passed via reference
- Method overloading
- name methods the same, but must have different parameters
- cannot overload changing only the return type
- helps with polymorphism
- will try implicit conversions if an explicit method that can handle doesn’t exist
- don’t overload names of unrelated methods
- can also overload the constructor
- static
- when you want to define member independent of an object
- can be used without reference to the object
- can act as a global variable for the class
- all instances of the class share the same static variable
- do not have a this reference
- static blocks
- executed when class is first loaded
- can be used when certain actions must occur before object initialization
- nested and inner classes
- classes defined within a class are bound by the outer class
- inner classes can access members of the outer class
- varargs
- methods can have variable length parameters
- “(int … v)” format
- acts as an array
- must be last parameter
- cannot have more than one type of varargs
- can overload
- may have errors if there is potential ambiguity e.g. can’t tell type of passing with no args and overloaded method
- Inheritance
- Basics
- use extends keyword in class
- can only specify one superclass
- Member Access
- inheriting does not overrule the private access restriction
- usually not an issue because Java programmers tend to provide setters and getters
- Constructors
- the constructor of the superclass constructs the superclass portion and the constructor of the subclass constructs the subclass part
- user super(parameter-list) in the subclass constructor
- super must always be executed first
- constructors are executed top-down (superclass must run first)
- super to access superclass members
- can access with super.member
- most applicable when the member name of a subclass hides members of the superclass of the same name
- Superclass References and Subclass Objects
- a reference variable of a superclass can be assigned a reference to any object derived from that superclass
- but the object will only have access to members available on the superclass
- Method Overriding
- can override own specific version of the method in the subclass
- signatures must be identical
- dynamic method dispatch is the mechanism by which overridden method is resolved at runtime
- Java determines which method to execute based on the object type
- allows different versions of the method to be executed
- allows a general class to specify methods that will be common to all of its derivatives
- subclasses can define own specific implementation
- adds flexibility while enforcing a consistent interface
- Abstract Classes
- defines only the generalized form
- abstract classes have at least one abstract member
- can only be used on instance methods
- all methods must be implemented for it to not be an abstract class
- can contain concrete methods as well
- Using final
- can be used on class and members
- prevents subclassing or overriding
- useful for constants
- The Object Class
- implicit superclass of all other classes
- Packages and Interfaces
- Packages
- provides a way to name a collection of classes
- helps avoid name collisions by partitioning namespaces
- defined with package keyword
- organized in same structure as directories
- java run-time uses current working directory, but classpath can be specified as well
- Packages and Member Access
- public is accessible by all
- protected is acessible within the package and outside package if its in a subclass
- default members only accessible within the package
- private member only accessible in class
- Importing
- can use fully qualified name
- can also import package
- use * to get all in namespace
- Java Class library
- java.lang automatically imported
- others that need to be imported: java.io, java.net, java.util, java.awt
- Interfaces
- similar to abstract classes
- defines what class must do but not how
- can be implemented by numerous classes
- a class can implement multiple interfaces
- can add default implementations, static methods, and private methods
- public interfaces must be in file of same name
- methods are implicitly public
- variables are public, final, static (essentially constants)
- methods implementing an interface must be public and type signatures must be the same
- like a reference variable can be assigned a subclass, you can assign classes that implement an interface
- interfaces can be extended by other interfaces
- Default Interface Methods
- must use keyword default
- helps prevent breaking changes to popular interfaces
- allows implementation in some cases
- Multiple Inheritance
- if class implements method that takes precedence
- if multiple default implementations from two interfaces, error
- if an interface extends another interface, will default to the inheriting interface e.g. Beta extends Alpha, Beta’s version will take precedence
- Exeception Handling
- Exception Hierarchy
- all exception classes derived from Throwable
- two direct subclasses are Error and Exception
- Errors are related to errors in the JVM and not in program, usually beyond your control and not dealt with
- Exceptions are the result of program activity
- RuntimeException important subclass of Exception to represent various common runtime errors
- Fundamentals
- try, catch, throw, throws, finally
- exceptions are monitored in try block
- catch handles errors in try block based on specified exception types
- can manually throw with throw
- checked exceptions must be specified with throws in signature
- finally executed after try/catch block
- uncaught exceptions
- displays stack trace, error and terminates execution by default
- can catch multiple exception types
- put subclass exceptions first since superclass can catch subclass exceptions
- nested try blocks allow specific handling of different cases
- Throwing an Exception
- needs to throw an exception object
- can rethrow in catch block
- Throws
- methods that throw errors that aren’t RuntimeException or Error must specify throws in signature
- error must be handled by caller
- Additional features
- try-with-resource statement
- catch two or more types in catch using “|”
- final rethrow (more precise rethrow)
- chained exceptions can point to underlying cause
- use cause exception in constructor of new exception
- define your own exception subclasses
- Using I/O
- Streams
- java I/O is performed throug streams
- produces or consumes information
- modern versions have byte streams (original) and character streams
- Byte stream
- top abstract classes are InputStream and OutputStream
- Character stream
- top abstract classes are Reader and Writer
- operate on unicode characters
- Predefined Streams
- System.in, System.out, System.err
- they are byte streams since that was original Java specification
- preferred method is to use character oriented streams in commercial code
- Reading and Writing Files Using Byte Streams
- to create byte stream linked to a file use FileInputStream or FileOutputStream
- use “read()” to read file
- call “close()” when done
- common to call “close()” in finally block
- catch IOExceptions
- Automatically closing files
- try(FileInputStream fin = new FileInputStream(filename)) {}
- can specify multiple resources with semi-colon
- Reading and Writing Binary Data
- can use DataInputStream and DataOutputStream to write and read primitives
- Random-Access Files
- use “RandomAccessFile”
- implements DataInput and DatOutput methods
- can use seek to set file pointer
- Character Based Streams
- Can wrap byte stream in Reader
- Buffered Reader br = new BufferedReader(new InputStreamReader(System.in));
- read method reads single unicode character
- can use PrintWriter to output to console
- File I/O Using Character Streams
- Use FileWriter and FileReader
- Java’s Type Wrappers to Convert Numeric Strings
- Double, Float, Long, Integer, Short, Byte
- wrap primitive types
- act as objects and give you parsing methods
- Multithreading Programming
- Fundamentals
- lets you utilize idle time that is present in most programs
- Thread Class and Runnable Interface
- to create a new thread either extend Thread class or implement Runnable interface
- instantiate object Thread
- need to define run method
- call start on thread object
- sleep lets you suspend execution for some period of time
- can create thread in constructor and also static factor method to make easier
- may want to extend class if you want to override any other thread methods otherwise implement Runnable
- Determining When a Thread Ends
- can check isAlive
- another option is call join on thread which will cause calling thread to wait until over
- can set priority which gives greater potential access to CPU
- Synchronization
- objects have monitor which locks access
- object with synchronized method will prevent other threads from accessing at same time
- if you can’t modify object, can use synchronized block to lock object
- Thread Communication
- if thread has monitor for an object and is blocked, can release lock by using wait
- the sleeping thread can be awakened when some other thread enters the same monitor and calls notify or notifyAll
- possible for sleeping thread to be awakened due to spurious wake up so good to place in loop that checks the condition thread is waiting on
- Suspending, Resuming and Stopping Threads
- originally ahd suspend, resume, and stop methods, but deprecated due to deadlock issues
- can design run method to check if thread should suspend, resume or stop
- while(suspended) {wait()}; if (stopped) break;
- Enumerations, AutoBoxing, Static Import, and Annotations
- Enumerations
- list of named constants
- can use in switch
- they are class types can have instance variables, constructors, methods, etc
- values(): all members
- valuesOf(): takes string and returns member
- enumeration constant is an object with the enumeration type
- enumerations can’t inherit or be inherited
- Autoboxing
- implicit conversions from primitive to type wrapper e.g. int to Int
- can use with variable references, parameter passing, return values, etc.
- e.g. Double val = 123.0;
- primitive types more efficient only use if type wrapper is necessary
- Static Import
- can import static method
- e.g. import static java.lang.Math.sqrt;
- good if plan on using multiple times not a few
- brining in too many can cause name conflicts
- Annotations
- used to embed information to source file
- used by tools
- based on interface
- does not change the actions of the program
- can annotate any declarations
- Generics
- Fundamentals
- parameterized types
- many algorithms logically the same
- allows better code reuse, type safety, and error reduction
- previously done with using Object reference and casting
- class Gen<T>
- generic type doesn’t exist at runtime
- compiler removes all generic types and substitutes with necessary casts
- only works with reference types
- Bounded Types
- allow only certain types
- <T extends superclass>
- can keep types compatible
- Wildcard Arguments
- sometimes not flexible enough
- e.g. NumericFns<Integer> comparing NumericFns<Double> wouldn’t work if arg type is NumericFns<T>
- can use wildcard args e.g. NumericFns<?> or NumericFns<? extends superclass>
- can also set lowerbound with <? super subclass>
- can define generic methods, constructors, interfaces
- Type Inference with Diamond Operator
- can reduce some of the verbosity
- TwoGen<Integer, String> tbOb = new TwoGen<>(42, “testing”)
- var tbOb = new TwoGen<Integer, String>(42, “testing”)
- Erasure
- type information is removed when code is compiled
- i.e. type parameter replaced with Object type if no explicit bound set
- no type parameters exist at runtime
- can cause issues with overloaded methods
- Restrictions
- can’t create instance of type parameter
- no static member can use type parameter declared by enclosing class
- can’t instantiate array whose elemnt type is a type parameter e.g. vals = new T[10];
- can’t create an array of type-specific generic references e.g. Gen<Integer> gens[] = new Gen<Integer>[10];
- Lambda Expressions and Method References
- Introduction
- anonymous methods
- lambda expressions also refered to as closures
- defined with arrow operatore e.g. () -> 3
- can be single expression or block
- functional interface must have one and only one abstract method
- lambda forms the implementation of the abstract method of the functional interface
- works with generics
- can use local variables in enclosing scope, but cannot modify
- can use and modify instance variables
- Method References
- can pass method reference of static method with “ClassName::methodName”
- pass method reference for specific instance with “objRef::methodName”
- can pass instance method without specifying specific instance with “ClassName::instanceMethodName”
- the first parameter of the functional interface must match the invoking object and second parameters matches parameters of the method
- constructor references passed with classname::new
- Predefined Functional Interfaces
- UnaryOperator<T>: applies to obejct of type T and returns type T
- Binary Operator<T>: applies to two objects of type T and returns type T
- Consumer<T>: apply operation on object of type T
- Supplier<T>: return an object of type T
- Function<T,R>: apply operation on object of type T and return type R
- Predicate<T>: determine if object fulfills some criteria and return boolean
Like this:
Like Loading...