Why can't static methods be abstract in Java?

后端 未结 25 2189
不思量自难忘°
不思量自难忘° 2020-11-22 08:34

The question is in Java why can\'t I define an abstract static method? for example

abstract class foo {
    abstract void bar( ); // <-- this is ok
    ab         


        
相关标签:
25条回答
  • 2020-11-22 08:57

    As per Java doc:

    A static method is a method that is associated with the class in which it is defined rather than with any object. Every instance of the class shares its static methods

    In Java 8, along with default methods static methods are also allowed in an interface. This makes it easier for us to organize helper methods in our libraries. We can keep static methods specific to an interface in the same interface rather than in a separate class.

    A nice example of this is:

    list.sort(ordering);
    

    instead of

    Collections.sort(list, ordering);
    

    Another example of using static methods is also given in doc itself:

    public interface TimeClient {
        // ...
        static public ZoneId getZoneId (String zoneString) {
            try {
                return ZoneId.of(zoneString);
            } catch (DateTimeException e) {
                System.err.println("Invalid time zone: " + zoneString +
                    "; using default time zone instead.");
                return ZoneId.systemDefault();
            }
        }
    
        default public ZonedDateTime getZonedDateTime(String zoneString) {
            return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString));
        }    
    }
    
    0 讨论(0)
  • 2020-11-22 08:57

    You can do this with interfaces in Java 8.

    This is the official documentation about it:

    https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html

    0 讨论(0)
  • 2020-11-22 08:59

    Because 'abstract' means the method is meant to be overridden and one can't override 'static' methods.

    0 讨论(0)
  • 2020-11-22 08:59

    Because if a class extends an abstract class then it has to override abstract methods and that is mandatory. And since static methods are class methods resolved at compile time whereas overridden methods are instance methods resolved at runtime and following dynamic polymorphism.

    0 讨论(0)
  • 2020-11-22 09:00

    You can't override a static method, so making it abstract would be meaningless. Moreover, a static method in an abstract class would belong to that class, and not the overriding class, so couldn't be used anyway.

    0 讨论(0)
  • 2020-11-22 09:00

    This is a terrible language design and really no reason as to why it can't be possible.

    In fact, here is an implementation on how it CAN be done in JAVA:

    public class Main {
    
            public static void main(String[] args) {
                    // This is done once in your application, usually at startup
                    Request.setRequest(new RequestImplementationOther());
    
                    Request.doSomething();
            }
    
            public static final class RequestImplementationDefault extends Request {
                    @Override
                    void doSomethingImpl() {
                            System.out.println("I am doing something AAAAAA");
                    }
            }
    
            public static final class RequestImplementaionOther extends Request {
                    @Override
                    void doSomethingImpl() {
                            System.out.println("I am doing something BBBBBB");
                    }
            }
    
            // Static methods in here can be overriden
            public static abstract class Request {
    
                    abstract void doSomethingImpl();
    
                    // Static method
                    public static void doSomething() {
                            getRequest().doSomethingImpl();
                    }
    
                    private static Request request;
                    private static Request getRequest() {
                            // If setRequest is never called prior, it will default to a default implementation. Of course you could ignore that too. 
                            if ( request == null ) {
                                    return request = new RequestImplementationDefault();
                            }
                            return request;
                    }
                    public static Request setRequest(Request r){
                            return request = r;
                    }
    
            }
    }
    

    ================= Old example below =================

    Look for getRequest, and getRequestImpl ... setInstance can be called to alter the implementation before the call is made.

    import java.io.IOException;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    import org.springframework.web.context.request.RequestContextHolder;
    import org.springframework.web.context.request.ServletRequestAttributes;
    
    /**
     * @author Mo. Joseph
     * @date 16 mar 2012
     **/
    
    public abstract class Core {
    
    
        // ---------------------------------------------------------------        
        private static Core singleton; 
        private static Core getInstance() {
            if ( singleton == null )
                setInstance( new Core.CoreDefaultImpl() );  // See bottom for CoreDefaultImpl
    
            return singleton;
        }    
    
        public static void setInstance(Core core) {
            Core.singleton = core;
        }
        // ---------------------------------------------------------------        
    
    
    
        // Static public method
        public static HttpServletRequest getRequest() {      
            return getInstance().getRequestImpl();
        }
    
    
        // A new implementation would override this one and call setInstance above with that implementation instance
        protected abstract HttpServletRequest getRequestImpl();
    
    
    
    
        // ============================ CLASSES =================================
    
        // ======================================================================
        // == Two example implementations, to alter getRequest() call behaviour 
        // == getInstance() have to be called in all static methods for this to work
        // == static method getRequest is altered through implementation of getRequestImpl
        // ======================================================================
    
        /** Static inner class CoreDefaultImpl */
        public static class CoreDefaultImpl extends Core { 
            protected HttpServletRequest getRequestImpl() {
                return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            }
        }
    
         /** Static inner class CoreTestImpl : Alternative implementation */
        public static class CoreTestImpl extends Core { 
            protected HttpServletRequest getRequestImpl() {
                return new MockedRequest();
            }
        }       
    
    }
    

    Used as follow:

    static {
         Core.setSingleton(new Core.CoreDefaultImpl());
    
         // Or
    
         Core.setSingleton(new Core.CoreTestImpl());
    
         // Later in the application you might use
    
         Core.getRequest(); 
    
    }
    
    0 讨论(0)
提交回复
热议问题