Example Custom serialization in Java:

import java.io.*;

class Person implements Serializable {
    private static final long serialVersionUID = 1L;

    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    private void writeObject(ObjectOutputStream out) throws IOException {
        out.writeUTF(name);
        out.writeInt(age);
    }

    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
        name = in.readUTF();
        age = in.readInt();
    }
}

public class CustomSerializationExample {
    public static void main(String[] args) throws Exception {
        Person person = new Person("John Doe", 30);

        try (FileOutputStream fos = new FileOutputStream("person.ser");
             ObjectOutputStream oos = new ObjectOutputStream(fos)) {

            oos.writeObject(person);
        }

        try (FileInputStream fis = new FileInputStream("person.ser");
             ObjectInputStream ois = new ObjectInputStream(fis)) {

            Person deserializedPerson = (Person) ois.readObject();
            System.out.println("Deserialized Person: " + deserializedPerson.getName() + ", " + deserializedPerson.getAge());
        }
    }
}

In this example, the Person class implements the Serializable interface and provides custom serialization logic using the writeObject and readObject methods. The writeObject method writes the name and age fields to the output stream, while the readObject method reads these fields from the input stream and sets them to the Person object.

The main method creates an instance of the Person class and serializes it to a file using an ObjectOutputStream. The same instance is then deserialized from the file using an ObjectInputStream and the resulting Person object is displayed on the console.