Why does Java claim to have two declared methods when it comes to bounded generics?
Has the following definitions:
public interface BaseService<T,ID> { T findOne(ID id); } public class BaseServiceImpl<T,ID extends Serializable> implements BaseService<T,ID> { @Override public T findOne(ID id) { return null; } }
Why baseserviceimpl class. Getdeclaraedmethods() returns 2 methods:
> public java. lang.Object BaseServiceImpl. findOne(java.io.Serializable) > public java. lang.Object BaseServiceImpl. findOne(java.lang.Object)
Is there any way to filter out these?
Solution
This is the result of type erasure At the bytecode level, the universal signature is only an additional attribute of a method and is not used for JVM method dispatch The actual bytecode level signature is derived from the first type bound by the type variable. For example, for the type variable t extends number & serializable, the original signature substitution T will be number
For your statement,
public interface BaseService<T,ID> { T findOne(ID id); }
T and ID are replaced by object; The erasure signature of the method is object findone (object)
For subtype declarations
public class BaseServiceImpl<T,ID> { @Override public T findOne(ID id) { return null; } }
The deleted ID type extension serializable is serializable, which makes the implementation method have the erased signature object findone (serializable)
In order to ensure that the code uses the BaseService interface and calls the method object findone (object), the implementation method will be found. The compiler generates a bridge method with the signature object findone (object) and contains an ordinary delegate of the object findone (serializable). If necessary, perform type conversion
You can identify the bridge method by calling isbridge () on the method instance
You can also use types to erase knowledge of how to affect results By changing the declaration to
public class BaseServiceImpl<T,ID extends Object&Serializable> implements BaseService<T,ID> { @Override public T findOne(ID id) { return null; } }
There is no semantic difference in the generic type system, but the extension of ID extends object & serializable will be object. Therefore, the result erasure of findone method will be the same as that of interface method, and no bridging method will be required in this case