Quando instancio um objeto e passo seus parâmetros, utilizo o .add, mas ao fazer isso o objeto adicionado anteriormente se torna o que eu acabei de criar, assim:
objeto 1
nome: Caneta
codigo: 123
objeto 2
nome: Lápis
código: 555
Após utilizar o .toString o console imprime:
Lápis
555
Lápis
555
O código é esse:
    int opcao;
    int qtdProdutos = 0;
    Scanner scanner = new Scanner(System.in);
    List<Produto> produtos = new ArrayList<Produto>();
    
    do {
        System.out.println("\n****\nMENU\n****\n");
        System.out.println("1 - Incluir produto");
        System.out.println("2 - Consultar produto");
        System.out.println("3 - Listagem de produtos");
        System.out.println("4 - Vendas por período - detalhado");
        System.out.println("5 - Realizar venda");
        System.out.println("0 - Sair");
        System.out.print("Opção: ");
        opcao = scanner.nextInt();
        scanner.nextLine();
        if (opcao == 1) {
            
          Produto produto = new Produto();
            
          System.out.println("Código: ");
          produto.setCodigo(scanner.next());
          System.out.println("Nome: ");
          produto.setNome(scanner.next());
          System.out.println("Valor: ");
          produto.setValor(scanner.nextDouble());
          System.out.println("Estoque: ");
          produto.setEstoque(scanner.nextInt());
          produtos.add(qtdProdutos, produto);
                         
          qtdProdutos++;