简体   繁体   中英

How can I access a method of an “unnamed” class?

public class Test {
    public static void main(String[] args) {
        DemoAbstractClass abstractClass = new DemoAbstractClass() {
            private String val;

            @Override
            public void runner() {
                val = "test";
                System.out.println(val);
                this.run();
            }

            public String getVal() {
                return val;
            }
        };

        abstractClass.runner();

        /**
         * I want to access getVal method here
         */
    }
}

abstract class DemoAbstractClass {
    public void run() {
        System.out.println("running");
    }

    public abstract void runner();
}

Here, I'm declaring an abstract class DemoAbstractClass. I can obviously create a new class that extends this class and add this method to it. But, I would prefer not doing that in my scenario. Is there any other way to access getVal method in above code??

You can't. You need to make a proper (non-anomous) class out of it. Make it an inner private class if you want to limit its scope.

Alternatively, you could use a StringBuffer and share a referense to it between the methods. Not extremely clean however.

Related question:

Short of using reflection, you cannot as you have no access to the concrete type of the object to be able to bind the methodcall to

If you don want to do something like this in a sane manner, declare a named class and use that as the type of abstractClass

Unfortunately, if you cannot name the type, you cannot access the methods at the language level.

What you can do, though, is use the reflection API to get a Method object and invoke it on this object.

This, however, is pretty slow. A private class or private interface would be much faster.

I can obviously create a new class that extends this class and add this method to it.

You've already done this; the end result was an anonymous inner class: new DemoAbstractClass() { ... }; If you just moved that declaration into its own class -- you can even make it a private class -- you can access getVal.

Per your example above:

public class Test {
    public static void main(String[] args) {
        DemoClass abstractClass = new DemoClass();

        abstractClass.runner();

        /**
         * I want to access getVal method here
         */
        abstractClass.getVal(); // can do this here now
    }

    private class DemoClass extends DemoAbstractClass {

            private String val;

            @Override
            public void runner() {
                val = "test";
                System.out.println(val);
                this.run();
            }

            public String getVal() {
                return val;
            }
        }
    }
}

Another option is to make a StringBuilder a member of the main method and use the closure nature of anonymous inner methods:

public static void main(String[] args) {
    final StringBuilder value = new StringBuilder();
    DemoAbstractClass abstractClass = new DemoAbstractClass() {
        @Override
        public void runner() {
            value.append( "test" );
            System.out.println(val);
            this.run();
        }
    };

    abstractClass.runner();

    // use val here...
    String val = value.toString();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM