IntelliJ IDEA, Java syntax, types, operators, and encapsulation
In the previous lectures, we covered:
classDiagram
direction TB
A -- B : Association
C o-- D : Aggregation
E *-- F : Composition
G <|-- H : Inheritance
| Association (--) | "uses" or "knows about" |
| Aggregation (o--) | "has" - parts can exist independently |
| Composition (*--) | "owns" - parts cannot exist alone |
| Inheritance (<|--) | "is a" - child extends parent |
IntelliJ IDEA is one of the most popular Java IDEs (Integrated Development Environment):
Key shortcuts:
Shift + Shift | Search anything |
Ctrl + Space | Code completion |
Alt + Enter | Quick fixes and suggestions |
Ctrl + / | Comment/uncomment line |
Shift + F10 | Run current program |
JavaExercisessrc folder for your source code.
src folderfr.wayup.exercises.HelloWorld
fr.wayup.exercises and class HelloWorldpackage fr.wayup.exercises;
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
Click the green play button or press Shift+F10 to run!
package fr.wayup.exercises; ①
public class JavaSyntaxDemo { ②
private String demoVersion = "1.0"; ③
public JavaSyntaxDemo() { ④
// Initialization code
}
public String getDemoVersion() { ⑤
return this.demoVersion;
}
}
// Single-line comment
/* Multi-line comment
spanning multiple lines */
/** Javadoc comment - generates documentation */
;
int x = 10; // Statement ends with semicolon
{ }
if (x > 5) {
System.out.println("x is greater than 5");
}
Packages organize your classes and prevent naming conflicts:
package fr.wayup.banking; // This class belongs to this package
import java.util.ArrayList; // Import a specific class
import java.time.*; // Import all classes from a package
public class Account {
private ArrayList transactions;
private LocalDate openDate;
}
com.company.projectjava.lang is imported automatically (String, System, etc.)| Primitive Types | Reference Types (Objects) |
|---|---|
| Built into the language | Created from classes |
| Stored directly in memory | Stored as references (pointers) |
Lowercase names: int, double |
Uppercase names: String, ArrayList |
| Have default values (0, false) | Default to null |
| Cannot be null | Can be null |
int count = 10; // Primitive
String message = "Hello"; // Reference (Object)
| Type | Size | Range | Example |
|---|---|---|---|
byte |
1 byte | -128 to 127 | byte b = 100; |
short |
2 bytes | -32,768 to 32,767 | short s = 1000; |
int |
4 bytes | ±2.1 billion | int i = 100000; |
long |
8 bytes | ±9.2 quintillion | long l = 100000L; |
int for most integer values. Use long with L suffix for large numbers.
| Type | Size | Precision | Example |
|---|---|---|---|
float |
4 bytes | ~7 decimal digits | float f = 3.14f; |
double |
8 bytes | ~15 decimal digits | double d = 3.14159; |
float price = 19.99f; // Note the 'f' suffix
double pi = 3.14159265359; // Default for decimals
double scientific = 1.5e10; // Scientific notation: 1.5 × 10^10
double for decimal numbers (it's the default).
| Type | Size | Values | Example |
|---|---|---|---|
boolean |
1 bit* | true or false |
boolean active = true; |
char |
2 bytes | Unicode character | char grade = 'A'; |
boolean isLoggedIn = false;
boolean hasPermission = true;
char firstLetter = 'A'; // Single quotes for char
char unicode = '\u0041'; // Unicode: also 'A'
char newline = '\n'; // Escape character
char uses single quotes 'A', while String uses double quotes "Hello"
String is a reference type (object), but it's used so often it has special syntax:
// String creation
String greeting = "Hello, World!"; // String literal
String name = new String("Alice"); // Using constructor (rarely needed)
// String operations
String fullName = "John" + " " + "Doe"; // Concatenation
int length = greeting.length(); // 13
String upper = greeting.toUpperCase(); // "HELLO, WORLD!"
boolean starts = greeting.startsWith("Hello"); // true
String sub = greeting.substring(0, 5); // "Hello"
varSince Java 10, you can use var to let the compiler infer the type:
// Traditional declarations
String message = "Hello";
ArrayList<String> names = new ArrayList<String>();
Map<String, List<Integer>> data = new HashMap<String, List<Integer>>();
// With var - compiler infers the type
var message = "Hello"; // Inferred as String
var names = new ArrayList<String>(); // Inferred as ArrayList<String>
var data = new HashMap<String, List<Integer>>(); // Much cleaner!
var only works for local variables with initializers. Not for fields, parameters, or return types.
var// Type is obvious from right side
var count = 0;
var name = "Alice";
var list = new ArrayList<String>();
// Long generic types
var map = new HashMap<String, List<Integer>>();
// With streams
var filtered = names.stream()
.filter(n -> n.startsWith("A"))
.toList();
// Type not clear
var result = getResult(); // What type?
var x = calculate(); // Unclear
// Numeric literals
var num = 3.14; // double or float?
var id = 100; // int or long?
// Diamond with var (fails)
var list = new ArrayList<>(); // Error!
var Best Practices| Rule | Example |
|---|---|
| Use meaningful variable names | var customerList = getCustomers(); (type clear from name) |
| Use when type is on the right side | var scanner = new Scanner(System.in); |
| Avoid with primitive literals | Use int count = 0; not var count = 0; |
| Great for loop variables | for (var item : collection) { ... } |
var is about reducing verbosity, not hiding types. If the type isn't obvious, use explicit declaration.
| Operator | Description | Example | Result |
|---|---|---|---|
+ | Addition | 5 + 3 | 8 |
- | Subtraction | 5 - 3 | 2 |
* | Multiplication | 5 * 3 | 15 |
/ | Division | 5 / 3 | 1 (integer!) |
% | Modulo (remainder) | 5 % 3 | 2 |
int a = 10, b = 3;
System.out.println(a / b); // 3 (integer division!)
System.out.println(a % b); // 1 (remainder)
System.out.println(10.0 / 3); // 3.333... (double division)
int i = 10;
// Increment / Decrement
i++; // i is now 11 (post-increment)
++i; // i is now 12 (pre-increment)
i--; // i is now 11
// Compound assignment operators
i += 5; // Same as: i = i + 5 → i is 16
i -= 3; // Same as: i = i - 3 → i is 13
i *= 2; // Same as: i = i * 2 → i is 26
i /= 2; // Same as: i = i / 2 → i is 13
// Pre vs Post increment
int a = 5;
int b = a++; // b = 5, a = 6 (use then increment)
int c = ++a; // c = 7, a = 7 (increment then use)
| Operator | Description | Example | Result |
|---|---|---|---|
== | Equal to | 5 == 5 | true |
!= | Not equal to | 5 != 3 | true |
> | Greater than | 5 > 3 | true |
< | Less than | 5 < 3 | false |
>= | Greater or equal | 5 >= 5 | true |
<= | Less or equal | 5 <= 3 | false |
.equals() instead of ==!
String a = "hello";
a.equals("hello") // true - correct way
a == "hello" // may be false - compares references!
| Operator | Description | Example | Result |
|---|---|---|---|
&& | AND | true && false | false |
|| | OR | true || false | true |
! | NOT | !true | false |
int age = 25;
boolean hasLicense = true;
// Combining conditions
boolean canDrive = age >= 18 && hasLicense; // true
boolean isMinorOrNoLicense = age < 18 || !hasLicense; // false
// Short-circuit evaluation
if (name != null && name.length() > 0) {
// Safe: second part only evaluated if first is true
}
Access modifiers control who can see and use your classes, fields, and methods:
| Modifier | Class | Package | Subclass | World |
|---|---|---|---|---|
public |
✓ | ✓ | ✓ | ✓ |
protected |
✓ | ✓ | ✓ | ✗ |
| (default) | ✓ | ✓ | ✗ | ✗ |
private |
✓ | ✗ | ✗ | ✗ |
private, then widen access only when needed.
public class BankAccount {
public String accountNumber; // Accessible from anywhere
protected double balance; // Package + subclasses
String bankName; // Default: package only
private String pin; // Only within this class
public void deposit(double amount) { // Public method
if (amount > 0) {
this.balance += amount;
logTransaction("Deposit: " + amount);
}
}
private void logTransaction(String msg) { // Private helper
System.out.println(msg);
}
}
Encapsulation = hiding internal details and providing controlled access.
classDiagram
class BankAccount {
-double balance
-String pin
+getBalance() double
+deposit(amount) void
+withdraw(amount) boolean
}
- = private, + = public
private, provide getters/setterspublic class BankAccount {
private double balance; // Private field
// Getter - read access
public double getBalance() {
return this.balance;
}
// Setter - controlled write access
public void setBalance(double balance) {
if (balance >= 0) { // Validation!
this.balance = balance;
} else {
throw new IllegalArgumentException("Balance cannot be negative");
}
}
}
getFieldName() - returns the valuesetFieldName(value) - sets with validationpublic class Customer {
private String name;
private String email;
public Customer(String name, String email) {
setName(name); // Use setters for validation
setEmail(email);
}
public String getName() { return name; }
public void setName(String name) {
if (name != null && !name.isEmpty()) {
this.name = name;
}
}
public String getEmail() { return email; }
public void setEmail(String email) {
if (email != null && email.contains("@")) {
this.email = email;
}
}
}
Converting values from one type to another:
int myInt = 100;
double myDouble = myInt; // Automatic: 100.0
double myDouble = 9.78;
int myInt = (int) myDouble; // Cast required: 9
// Widening - automatic, safe
byte b = 10;
int i = b; // OK
long l = i; // OK
double d = l; // OK
// Narrowing - requires cast, may lose data
double price = 19.99;
int roundedPrice = (int) price; // 19 (decimal lost)
long bigNumber = 10_000_000_000L;
int smaller = (int) bigNumber; // OVERFLOW! Wrong value
// String conversions
int age = Integer.parseInt("25");
double salary = Double.parseDouble("50000.50");
String ageStr = String.valueOf(age); // "25"
String concat = "" + age; // "25" (quick way)
Create Java classes based on this class diagram:
classDiagram
direction LR
class Customer {
-String name
-String address
}
class Account {
-String accountNumber
-double balance
}
class SavingsAccount {
-double interestRate
}
class InvestmentAccount
Customer "1" -- "0..*" Account
Account <|-- SavingsAccount
Account <|-- InvestmentAccount
For each class in the diagram, implement:
SavingsAccount and InvestmentAccount extend AccountCustomer can have multiple accounts (0 or more)ArrayList<Account> in Customer to store accountsAdd the following methods to your SavingsAccount class:
deposit(double amount)
withdraw(double amount)
computeInterest()
applyInterest()
int, double) and objects (String)private → default → protected → public