Lesson 4: Creating Classes#
In this lesson, you’ll learn different ways to create Java classes and use code actions to generate boilerplate code.
Learning Objectives#
By the end of this lesson, you’ll be able to:
- Create classes using the file explorer
- Use fuzzy finder to create files quickly
- Generate constructors, getters, and setters
- Use code actions effectively
Method 1: File Explorer#
The traditional way using nvim-tree:
- Open file explorer:
<Space>ne - Navigate to
src/main/java/com/example/ - Press
a(add file) - Type filename:
Person.java - Press
Enter
The file opens, ready for editing.
Method 2: Fuzzy Finder#
Faster way using Telescope:
- Press
<Space>ff(find files) - Start typing the path:
src/main/java/com/example/Person.java - If file doesn’t exist, press
<Ctrl-n>to create it - Confirm creation
Note: This creates the file immediately when you select a non-existent path.
Method 3: Command Line#
From Neovim command mode:
:e src/main/java/com/example/Person.javaPress Enter and start editing. Save with :w to create the file.
Creating a Basic Class#
Let’s create a Person class:
package com.example;
public class Person {
private String name;
private int age;
private String email;
}Type this out (practicing Vim motions!). Save with <Space>w.
Using Code Actions#
Code actions are context-aware commands that jdtls provides. They’re extremely powerful for Java development.
Accessing Code Actions#
Place your cursor on a class, method, or variable and press:
<Space>ca(Leader key + ‘ca’ for Code Actions)
Generating Constructors#
- Create your class with fields (like Person above)
- Move cursor to the class name line (
public class Person) - Press
<Space>ca - Select “Generate constructor”
- Choose which fields to include
- Constructor is generated automatically
Example result:
public class Person {
private String name;
private int age;
private String email;
public Person(String name, int age, String email) {
this.name = name;
this.age = age;
this.email = email;
}
}Generating Getters and Setters#
- Move cursor to a field (e.g.,
private String name) - Press
<Space>ca - Select “Generate getters and setters”
- Choose which fields
Or use code actions on the class itself to generate for all fields at once.
Example result:
public class Person {
private String name;
private int age;
private String email;
public Person(String name, int age, String email) {
this.name = name;
this.age = age;
this.email = email;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}Other Useful Code Actions#
| Action | Description |
|---|---|
| Generate toString() | Create string representation |
| Generate equals() and hashCode() | For object comparison |
| Implement methods | When implementing interface |
| Override methods | When extending class |
| Add imports | Import missing classes |
| Organize imports | Clean up import statements |
Organizing Imports#
If you have unused or missing imports:
- Press
<Space>caanywhere in the file - Select “Organize imports”
- Imports are cleaned up automatically
Or use the direct command:
:lua vim.lsp.buf.code_action({context = {only = {"source.organizeImports"}}})Practice Exercise: Create a Book Class#
Create a complete Book class with code actions:
Step 1: Create the file#
package com.example;
public class Book {
private String title;
private String author;
private int year;
private double price;
}Step 2: Generate constructor#
- Cursor on
class Book <Space>ca- Select “Generate constructor”
- Include all fields
Step 3: Generate getters and setters#
<Space>ca- Generate for all fields
Step 4: Add toString() method#
<Space>ca- Select “Generate toString()”
Step 5: Test your class#
Create a main method:
public static void main(String[] args) {
Book book = new Book("1984", "George Orwell", 1949, 15.99);
System.out.println(book.toString());
}Advanced: Interface Implementation#
Create an interface:
package com.example;
public interface Printable {
void print();
String getDescription();
}Implement it in Person:
public class Person implements Printable {
// ... existing code ...
}You’ll see an error (red squiggly line). Fix it:
- Cursor on
implements Printable - Press
<Space>ca - Select “Implement methods”
- Methods are generated with stubs
Common Code Actions#
Quick Fix#
When you see errors (red underlines):
- Move cursor to the error
- Press
<Space>ca - See suggested fixes
Examples:
- Add missing import
- Create missing method
- Change access modifier
- Assign to new variable
Extract to Method#
Select code in Visual mode, then:
- Press
vto enter Visual mode - Select lines to extract
- Press
<Space>ca - Select “Extract to method”
- Name the new method
Rename Symbol#
Better than find-and-replace:
- Cursor on class/method/variable name
- Press
<Space>rn(rename) - Type new name
- Press
Enter - All references updated across project
Keybindings Summary#
| Key | Action |
|---|---|
<Space>ca | Code actions |
<Space>rn | Rename symbol |
gd | Go to definition |
K | Show documentation |
<Space>ff | Find/create file |
<Space>ne | File explorer |
Tips#
- Explore code actions - Press
<Space>caon different elements to see what’s available - Use rename liberally - It’s safe and updates all references
- Let LSP generate boilerplate - Don’t type getters/setters manually
- Keep imports clean - Regularly organize imports
- Read error messages - Code actions often suggest the fix
What’s Next?#
In Lesson 5: Managing Packages, you’ll learn to organize code with Java packages.