Skip to content

Commit e937a27

Browse files
authored
Add nullability concept (#2584)
* Nullability concept added * Updating error message * Updating config.json * Linting issues and prerequisites updated in config.json * Addressing review comments * Removing trailing space Fixes #2553
1 parent 18c16d0 commit e937a27

File tree

16 files changed

+354
-0
lines changed

16 files changed

+354
-0
lines changed
+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"blurb": "In Java, the null literal is used to denote the absence of a value.",
3+
"authors": [
4+
"smcg468"
5+
],
6+
"contributors": []
7+
}

concepts/nullability/about.md

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# About
2+
3+
In Java, the [`null` literal][null-keyword] is used to denote the absence of a value.
4+
5+
[Primitive variables][primitive-data-types] in java all have a default value and therefore can never be `null`.
6+
By convention, they start with a lowercase letter e.g `int`
7+
8+
[Reference variables][reference-data-types] contain the memory address of an object and can have a value of null.
9+
These variables usually start with an uppercase e.g `String`
10+
11+
Attempting to assign a primitive variable a value of `null` will result in a compile time error as the variable always holds
12+
a default value of the type assigned.
13+
14+
```java
15+
//Throws compile time error stating the required type is int, but null was provided
16+
int number = null;
17+
```
18+
19+
Assigning a reference variable a `null` value will not result in a compile time error as reference variables are nullable.
20+
21+
```java
22+
//No error will occur as the String variable str is nullable
23+
String str = null;
24+
```
25+
26+
Whilst accessing a reference variable which has a value of `null` will compile fine, it will result in a `NullPointerException` being thrown at runtime.
27+
28+
```java
29+
int[] arr = null;
30+
31+
// Throws NullPointerException at runtime
32+
arr.Length;
33+
```
34+
35+
A [`NullPointerException` is thrown][null-pointer-exception] when trying to access a reference variable which is null but requires an object.
36+
37+
To safely work with nullable values, one should check if they are `null` before working with them which can be done using [equality operators][equality-operators] such as `==` or `!=`:
38+
39+
```java
40+
int[] arr = null;
41+
42+
if(arr != null) {
43+
System.out.println(arr.length);
44+
} else {
45+
//Perform an alternate action when arr is null
46+
}
47+
```
48+
49+
[null-keyword]: https://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.7
50+
[primitive-data-types]: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
51+
[reference-data-types]: https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.3
52+
[null-pointer-exception]: https://docs.oracle.com/javase/8/docs/api/java/lang/NullPointerException.html
53+
[equality-operators]: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/op2.html

concepts/nullability/introduction.md

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Introduction
2+
3+
In Java, the `null` literal is used to denote the absence of a value.
4+
5+
Primitive data types in java all have a default value and therefore can never be `null`.
6+
By convention, they start with a lowercase letter e.g `int`
7+
8+
Reference types contain the memory address of an object can have a value of null.
9+
These variables usually start with an uppercase e.g `String`
10+
11+
Attempting to assign a primitive variable a value of `null` will result in a compile time error as the variable always holds
12+
a primitive value of the type assigned.
13+
14+
```java
15+
//Throws compile time error stating the required type is int, but null was provided
16+
int number = null;
17+
```
18+
19+
Assigning a reference variable a `null` value will not result in a compile time error as reference variables are nullable.
20+
21+
```java
22+
//No error will occur as the String variable str is nullable
23+
String str = null;
24+
```

concepts/nullability/links.json

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
[
2+
{
3+
"url": "https://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.7",
4+
"description": "null-keyword"
5+
},
6+
{
7+
"url": "https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html",
8+
"description": "primitive-data-types"
9+
},
10+
{
11+
"url": "https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.3",
12+
"description": "reference-data-types"
13+
},
14+
{
15+
"url": "https://docs.oracle.com/javase/8/docs/api/java/lang/NullPointerException.html",
16+
"description": "null-pointer-exception"
17+
},
18+
{
19+
"url": "https://docs.oracle.com/javase/tutorial/java/nutsandbolts/op2.html",
20+
"description": "equality-operators"
21+
}
22+
]

config.json

+17
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,18 @@
234234
"switch-statement",
235235
"constructors"
236236
]
237+
},
238+
{
239+
"slug": "tim-from-marketing",
240+
"name": "Tim from Marketing",
241+
"uuid": "28bd20c5-4fdd-4660-9225-54f24aae24e4",
242+
"concepts": [
243+
"nullability"
244+
],
245+
"prerequisites": [
246+
"if-else-statements",
247+
"strings"
248+
]
237249
}
238250
],
239251
"practice": [
@@ -2088,6 +2100,11 @@
20882100
"slug": "lists",
20892101
"name": "Lists"
20902102
},
2103+
{
2104+
"uuid": "0718bff1-25ad-42bb-860d-1b0834beb9fc",
2105+
"slug": "nullability",
2106+
"name": "Nullability"
2107+
},
20912108
{
20922109
"uuid": "58529dab-0ef2-4943-ac12-a98ca79b922b",
20932110
"slug": "numbers",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Hints
2+
3+
## 1. Print a badge for an employee
4+
5+
- [String interpolation][string-interpolation] can be used to create description strings.
6+
- There is a [built-in method to convert a string to uppercase][to-upper-case].
7+
8+
## 2. Print a badge for a new employee
9+
10+
- You should check if the ID is `null` before using it.
11+
- You can use the [equality operators][equality-operators] to compare the value to `null`
12+
13+
## 3. Print a badge for the owner
14+
15+
- You should check if the department is `null` before using it.
16+
- You can use the [equality operators][equality-operators] to compare the value to `null`
17+
18+
[string-interpolation]: https://www.baeldung.com/java-string-interpolation
19+
[to-upper-case]:https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#toUpperCase--
20+
[equality-operators]: https://docs.oracle.com/cd/E21764_01/apirefs.1111/e17787/com/sigmadynamics/util/Null.html#isNull_java_lang_String_
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Instructions
2+
3+
In this exercise you'll be writing code to print name badges for factory employees.
4+
5+
## 1. Print a badge for an employee
6+
7+
Employees have an ID, name and department name. Employee badge labels are formatted as follows: `"[id] - name - DEPARTMENT"`.
8+
Implement the `Badge.print()` method to return an employee's badge label:
9+
10+
```java
11+
Badge badge = new Badge();
12+
badge.print(734, "Ernest Johnny Payne", "Strategic Communication");
13+
// => "[734] - Ernest Johnny Payne - STRATEGIC COMMUNICATION"
14+
```
15+
16+
Note that the department should be uppercased on the label.
17+
18+
## 2. Print a badge for a new employee
19+
20+
Due to a quirk in the computer system, new employees occasionally don't yet have an ID when they start working at the factory.
21+
As badges are required, they will receive a temporary badge without the ID prefix. Modify the `Badge.print()` method to support new employees that don't yet have an ID:
22+
23+
```java
24+
Badge badge = new Badge();
25+
Badge.print(null, "Jane Johnson", "Procurement");
26+
// => "Jane Johnson - PROCUREMENT"
27+
```
28+
29+
## 3. Print a badge for the owner
30+
31+
Even the factory's owner has to wear a badge at all times.
32+
However, an owner does not have a department. In this case, the label should print `"OWNER"` instead of the department name.
33+
Modify the `Badge.print()` method to print a label for the owner:
34+
35+
```java
36+
Badge badge = new Badge();
37+
badge.print(254, "Charlotte Hale", null);
38+
// => "[254] - Charlotte Hale - OWNER"
39+
```
40+
41+
Note that it is possible for the owner to also be a new employee:
42+
43+
```java
44+
Badge badge = new Badge();
45+
badge.print(null, "Charlotte Hale", null);
46+
// => "Charlotte Hale - OWNER"
47+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Introduction
2+
3+
## Nullability
4+
5+
In Java, the `null` literal is used to denote the absence of a value.
6+
7+
Primitive data types in java all have a default value and therefore can never be `null`.
8+
By convention, they start with a lowercase letter e.g `int`
9+
10+
Reference types contain the memory address of an object can
11+
have a value of null. These variables usually start with an uppercase e.g `String`
12+
13+
Attempting to assign a primitive variable a value of `null` will result in a compile time error as the variable always holds
14+
a primitive value of the type assigned.
15+
16+
```java
17+
//Throws compile time error stating the required type is int, but null was provided
18+
int number = null;
19+
```
20+
21+
Assigning a reference variable a `null` value will not result in a compile time error as reference variables are nullable.
22+
23+
```java
24+
//No error will occur as the String variable str is nullable
25+
String str = null;
26+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Introduction
2+
3+
## Nullability
4+
5+
%{concept:nullability}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"authors": [
3+
"smcg468"
4+
],
5+
"files": {
6+
"solution": [
7+
"src/main/java/Badge.java"
8+
],
9+
"test": [
10+
"src/test/java/BadgeTest.java"
11+
],
12+
"exemplar": [
13+
".meta/src/reference/java/Badge.java"
14+
],
15+
"invalidator": [
16+
"build.gradle"
17+
]
18+
},
19+
"forked_from": [
20+
"csharp/tim-from-marketing"
21+
],
22+
"blurb": "Learn about the null literal and nullable variables in java by printing name badges."
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Design
2+
3+
## Learning objectives
4+
5+
- Know of the existence of the `null` literal.
6+
- Know what a `NullPointerException` is and when it is thrown.
7+
- Know how to compare a value to `null`.
8+
9+
## Out of scope
10+
11+
- `java.util.Optional`
12+
13+
## Concepts
14+
15+
- `nullability`
16+
17+
## Prerequisites
18+
19+
- `strings`: strings will be compared to null and basic methods from strings will be called.
20+
- `if-else-statements`: using a conditional statement.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
public class Badge {
2+
3+
public String print(Integer id, String name, String department) {
4+
5+
String worksAt;
6+
7+
if (department == null) {
8+
worksAt = "OWNER";
9+
} else {
10+
worksAt = department.toUpperCase();
11+
}
12+
13+
if (id == null) {
14+
return name + " - " + worksAt;
15+
}
16+
17+
return "[" + id + "] - " + name + " - " + worksAt;
18+
}
19+
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
plugins {
2+
id "java"
3+
}
4+
5+
repositories {
6+
mavenCentral()
7+
}
8+
9+
dependencies {
10+
testImplementation platform("org.junit:junit-bom:5.10.0")
11+
testImplementation "org.junit.jupiter:junit-jupiter"
12+
testImplementation "org.assertj:assertj-core:3.15.0"
13+
}
14+
15+
test {
16+
useJUnitPlatform()
17+
18+
testLogging {
19+
exceptionFormat = "full"
20+
showStandardStreams = true
21+
events = ["passed", "failed", "skipped"]
22+
}
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
class Badge {
2+
public String print(Integer id, String name, String department) {
3+
throw new UnsupportedOperationException("Please implement the (static) Badge.print() method");
4+
}
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import org.junit.jupiter.api.DisplayName;
2+
import org.junit.jupiter.api.Tag;
3+
import org.junit.jupiter.api.Test;
4+
import static org.assertj.core.api.Assertions.assertThat;
5+
6+
public class BadgeTest {
7+
8+
@Test
9+
@Tag("task:1")
10+
@DisplayName("Printing a badge for an employee")
11+
public void labelForEmployee() {
12+
Badge badge = new Badge();
13+
assertThat(badge.print(17, "Ryder Herbert", "Marketing"))
14+
.isEqualTo("[17] - Ryder Herbert - MARKETING");
15+
}
16+
17+
@Test
18+
@Tag("task:2")
19+
@DisplayName("Printing a badge for a new employee")
20+
public void labelForNewEmployee() {
21+
Badge badge = new Badge();
22+
assertThat(badge.print(null, "Bogdan Rosario", "Marketing")).isEqualTo("Bogdan Rosario - MARKETING");
23+
}
24+
25+
@Test
26+
@Tag("task:3")
27+
@DisplayName("Printing a badge for the owner")
28+
public void labelForOwner() {
29+
Badge badge = new Badge();
30+
assertThat(badge.print(59, "Julie Sokato", null)).isEqualTo("[59] - Julie Sokato - OWNER");
31+
}
32+
33+
@Test
34+
@Tag("task:3")
35+
@DisplayName("Printing a badge for the owner who is a new employee")
36+
public void labelForNewOwner() {
37+
Badge badge = new Badge();
38+
assertThat(badge.print(null, "Amare Osei", null)).isEqualTo("Amare Osei - OWNER");
39+
}
40+
}

exercises/settings.gradle

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ include 'concept:football-match-reports'
1717
include 'concept:wizards-and-warriors'
1818
include 'concept:calculator-conundrum'
1919
include 'concept:logs-logs-logs'
20+
include 'concept:tim-from-marketing'
2021

2122
// practice exercises
2223
include 'practice:accumulate'
@@ -150,3 +151,4 @@ include 'practice:wordy'
150151
include 'practice:yacht'
151152
include 'practice:zebra-puzzle'
152153
include 'practice:zipper'
154+

0 commit comments

Comments
 (0)