Oi Diego, tudo bem?
A diferença entre checked e unchecked exceptions basicamente é que as checked exceptions você é obrigado a tratar, enquanto as unchecked não.
Por exemplo, temos duas exceções IOException e NullPointerException.
Se estamos trabalhando com arquivos, sabemos que um possível erro é o arquivo não existir então queremos obrigar que o programador trate este erro ou esteja ciente de que isto possa impactar na execução do programa. Por isto, IOException é checked.
Já a NullPointerException pode acontecer não por um problema do sistema, e sim por erro do programador. Então, como não sabemos quando pode acontecer, não somos obrigados a tratar esta exceção, por isso ela é unchecked.
Para criar uma exceção checked, a sua exceção deve herdar de Exception e para criar uma exceção unchecked, ela deve herdar de RuntimeException.
Já o throws nada mais é do que você simplesmente repassando a obrigação de tratamento da exceção para quem efetuar a chamada do método com o throws (Lembrando que só será obrigatório o tratamento se a exceção for checked).
Ficou um pouco mais claro? Caso continue com dúvida é só dar um toque!
Abraço!