Gray Matter
WorkshopJava Basics
WPILib 2027 is still in alpha: these pages change as the APIs settle.
LESSON 08

Java Basics

This page does not teach Java. It sends you to a free course, then names the few words that course leaves unconnected to robot code. The quiz at the end checks that you can read the next four lessons.

7 minutes
You’ll need
  • Nothing installed. No project, no robot, no build.
  • A free Codecademy account, which the course below needs.

Six pieces carry nearly all of the Java in this workshop: the class, the field, the constructor, the method, the lambda, and the dot. The course below teaches five of them.

Learn Java on Codecademy

Codecademy's Learn Java is free and runs in the browser, so there is nothing to install. Do not do all sixteen modules. Four of them cover almost everything the code here uses.

ModuleWhat it gives you
1. Hello WorldBraces, semicolons and comments. The punctuation you are about to stop noticing.
2. Variablesdouble, boolean, and what final does.
3. Object-Oriented JavaClasses, objects, new, constructors, methods. The one that matters most here.
4. Conditionals and Control Flowif, else, and the comparison operators: < > == != && || !.

Stop after Conditionals and Control Flow and come back. Arrays and string methods barely turn up here. Loops do, but not until Workshop 6, where a coroutine body is written as a real while loop. That lesson asks for the module by name.

Learn Java on Codecademy: free, in the browser, nothing to install

The six pieces

The course covers all of these except the lambda. This is what they look like in robot code, and it is the vocabulary the next four lessons assume you have.

PieceIn this workshop
classA kind of thing. class Arm is the drawing, and new Arm() builds one real arm from it.
fieldWhat an object owns for as long as it lives. private final TalonFX motor is one.
constructorSame name as the class, no return type. It runs once, the instant new Arm() runs, and you never call it by name.
methodA named block you can call. Read its return type first: void hands nothing back.
lambdaCode written down and handed over rather than run. () -> setVoltage(3.0) is one, and motor::stopMotor is the same idea written as a method reference.
the dota.b() means "on the thing a, call b". What you may type after a dot depends on the type in front of it.

A field carries two more words in front of its type. Marking it private means only code inside Arm.java may touch it, and public is the opposite. A final field points at one object for good. It locks the box and not the contents, so motor.setControl(...) still works while motor = new TalonFX(...) does not.

Writing public class Arm extends Mechanism gives Arm everything Mechanism can do. Mechanism has a method called runRepeatedly(...), for instance. Look through Arm.java and you will not find that method written anywhere. You can call it anyway.

Arm.java, branch mech-2-Commands: the method, the lambda, and the dot
/** Push the arm with a gentle voltage and keep pushing. Never finishes. */
public Command runSlow() {
return runRepeatedly(() -> setVoltage(3.0)).named("runSlow (hold)");
}
WATCH OUT

Writing a lambda runs nothing

Call arm.runSlow() and setVoltage(3.0) does not happen. The method builds a Command and hands it back with the lambda parked inside, and something else runs that command later.

This failure has no error message. The arm does not move, nothing logs, and nobody ever scheduled the command.

Check your work

Six questions on the lines above. Miss more than one and the course is worth another evening, because the next four lessons read code like this on every page.

Check yourself

In runRepeatedly(() -> setVoltage(3.0)), when does setVoltage(3.0) run?

Why is it motor::stopMotor and not motor.stopMotor() inside runRepeatedly(...)?

In private final TalonFX motor = new TalonFX(31, canivore), what does final stop you doing?

Arm.java never contains the word runRepeatedly, and runSlow() calls it. Why does that compile?

When does the code inside public Arm() run?

runRepeatedly(...).named("runSlow (hold)") compiles, but arm.runSlow().named("lift") does not. Why?

Pick an answer for each.
Arm.java on mech-2-Commands: the file these four lines come from