Como funciona a classe ArrayAdapter? O que é "tag"?

Era pra criar uma lista. Até aí blz. Ele criou duas classes. DadosPersonagem com:

private int ICONE;
private String TITULO;

Outra ViewElemento com:

private ImageView IMAGEM;
private TextView TITULO;

Claro, as duas com seus “get e set”.

Até aí blz. Depois ele me vem com isso:

public class MeuAdaptador extends ArrayAdapter{

public MeuAdaptador(@NonNull Context context, int resource) {
    super(context, resource);
}


@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
    View objetoView = convertView;
    ViewElemento personagem;

    if(convertView==null){
        LayoutInflater layoutInflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        objetoView=layoutInflater.inflate(R.layout.minha_celula, parent, false);

        personagem = new ViewElemento();

        personagem.setIMAGEM((ImageView) objetoView.findViewById(R.id.IconeCelula));
        personagem.setTITULO((TextView) objetoView.findViewById(R.id.TituloCelula));

        objetoView.setTag(personagem);
    }else{
        personagem = (ViewElemento) objetoView.getTag();
    }

    DadosPersonagem dados = (DadosPersonagem) this.getItem(position);

    personagem.getIMAGEM().setImageResource(dados.getICONE());
    personagem.getTITULO().setText(dados.getTITULO());

    return objetoView;
}

}

O que essa classe faz? O que é “tag”? Pra que serve essas coisas? Por que no método getView? E não no Add?