1

Let's start with a loose definition of 'marker interface' (please correct me or dispute this if you disagree):

If applied to a type, a marker interface doesn't provide any contract of methods to implement for that type. A marker interface gives semantic meaning.

So, OK, that's fine. However giving something a meaning has to ultimately have a practical consumption or usage elsewhere to be of benefit, right? So we may have two types that are different, but that are (for example) types related to 'scheduled tasks' in a system, so we may 'decorate' them both with an 'IAmTask' interface.

OK, so how do we then put that to practical use? I've read that:

One of the benefits of a marker interface is to 'communicate a semantic constraint/guarantee that doesn't otherwise change the API'.

OK, well a marker interface isn't defining a contract for methods that must be present on the type, so what's a practical example in code of how a semantic constraint/guarantee can be ultimately be returned to the user and consumed in a way that tightens up the intended guarantee to the consumer, without enforcing methods on the API? There must be a way to do this, otherwise we're simply declaring an essentially useless meaning.

  • 2
    How about java.util.RandomAccess which guarantees that indexed access to a list is efficient? All lists support indexed access, but only the ones that implement RandomAccess support efficient indexed access. – user253751 Jul 7 '17 at 0:06
  • In C# I've mainly seen them used for generic type constraints. – Ben Aaronson Jul 7 '17 at 16:15
  • I suggest reading about the design of the C++ STL. Marker interfaces are not very useful in most other languages I have worked with. – Frank Hileman Jul 10 '17 at 23:04
2

Since marker interfaces provide semantic meaning, they can be used like annotations to decorate a type, and you can use reflection to make decisions based on the semantics. The marker interface doesn't provide any compiler-enforceable contract.

For example, you have an interface UserRepository, and you have two implementations InMemoryUserRepository that stores users in memory and DatabaseUserRepository that stores users in a database.

interface UserRepository { def storeUser(user) }
class InMemoryUserRepository implements UserRepository { ... }
class DatabaseUserRepository implements UserRepository { ... }

I could introduce a marker interface to describe the semantics of the implementations. For example if I wanted to dynamically find implementations of UserRepository that have local semantics, I could introduce LocalRepository marker interface and have InMemoryUserRepository implement LocalRepository

interface UserRepository { def storeUser(user) }
interface LocalRepository {}
class InMemoryUserRepository implements UserRepository, LocalRepository { ... }
class DatabaseUserRepository implements UserRepository { ... }

The usefulness is that I can now distinguish the two repository classes from each other and decide to use the one with local semantics via reflection.

Some other examples of usages of marker interfaces:

  • Big(O) complexity of implementation e.g. java.util.RandomAccess (from @immibis comment). Maybe you have a dozen different sort algorithms. You could introduce marker interfaces with worst case and best case complexities.
  • Local vs. Remote. This is useful for dynamically picking a configuration for your system for testing. You could configure your dependency injection system to prefer local marked implementations when testing.
  • Serialization format. I may have a couple different serializers for different file formats that all have the same interface. I could introduce a marker interface to distinguish Json serializers and XML serializers, and use runtime preferences to use the file format. Or use a marker interface to describe their size footprint and choose the best serializer for network transfer based on size.
  • 1
    This is good for Java. For other languages, other things might be used for the same purpose. In .net, people use attributes. – Frank Hileman Jul 10 '17 at 23:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.