I don't know that annotations would ever replace an interface, but I can kind of see the allure. It all depends on the implementations though.
Annotations provide meta data to further describe code, which a consumer (most of the time) interprets at runtime using reflections. Using an interface, this contract of implementation is clearly defined.
You could have:
interface CrudDao<T> {
Serializable create(T t);
T read(Serializable id);
void update(T t);
void delete(T t);
}
This would be a cumbersome contract to implement, and would likely incur some sort of method chaining.
Instead you could do something like:
class SomeDao {
@Create
long create(SomeEntity e) { // code }
@Read
SomeEntity read(long id) { // code }
@Update
void update(SomeEntity e) { // code }
@Delete
void delete(SomeEntity e) { // code }
}
The drawback is that it would be cumbersome to use:
class CrudFactory {
long create(Class clazz, Object obj) {
// loop through methods
// find method with @Create
// call method
}
}
Annotations in this example would be overkill a majority of the time, IMO. There is something to be said about a clearly defined, well documented contract.