5

I just came to know that there is a process called in-line class with the help of which I can create a new object and modify its class methods on the fly. I don't know if I can create new methods and variables inside the in-line class and use them. So I did this experiment. My IDE did not show any error while creating a new method inside the in-line class. Now I don't know how to access the newly created method. My doubt is, can I create a new method while creating an in-line class?(If yes then how?) Or, in-line class is only for overloading the existing methods?

public class Main {
public static void main(String[] args) {
    Animals cat = new Animals("Cat") {
        @Override
        public void makeNoise() {
            System.out.println("MEOW MEOW");
        }

        public void color() {
            System.out.println("Color is: white");
        }
    };
    cat.makeNoise();
    cat.color(); //this is showing error
    }
}

Animal class

class Animals {
private String name;

public Animals(String name) {
    this.name = name;
}

public void makeNoise() {
    System.out.println("Sound of the animal");
}
}
Akash Nath
  • 63
  • 4
  • 3
    Short answer is you can't. Your anonymous inner class is a subclass of `Animals`, and your class `Animals` has no method color. Your variable `cat` is of type `Animals`, not the anonymous subclass. – Jeroen Steenbeeke Sep 13 '21 at 09:06
  • 1
    You would have to cast it to Main.$1 to make it runnable, but compiler will not let you do that anyway. Reflection might work, but I think this is not the goal of this excersice – Antoniossss Sep 13 '21 at 09:08
  • @Antoniossss: the primary reason the compiler won't let you do that is that it's an anonymous class. Any "name" that you find is an implementation detail by the compiler and can even vary between compiler instances. `var` lets you get around it because it allows you to have a variable of the unnameable type (as the highest-voted answer atm shows). – Joachim Sauer Sep 13 '21 at 09:18
  • btw it's not an "in-line" class, it's an inner class. Inline classes are a completely different thing, which don't exist in Java but exist in some other languages. – k314159 Sep 13 '21 at 09:50

2 Answers2

10

The easiest change: use var:

public static void main(String[] args) {
    var cat = new Animals("Cat") {
        @Override
        public void makeNoise() {
            System.out.println("MEOW MEOW");
        }

        public void color() {
            System.out.println("Color is: white");
        }
    };
    cat.makeNoise();
    cat.color();
}

This now works, because cat isn't an Animals, it's inferred as a more specific type than that - it's a class that doesn't have an accessible name, so you can't write it as an explicit variable.


In fact, you were able to access anonymous class methods prior to the introduction of var, in a way:

    new Animals("Cat") {
        // ...

        public void color() { ... }
    }.color();

This worked prior to var, because the expression new Animals("Cat") { ... } has a more specific type that Animals. The problem is, you can only invoke those extra methods directly on the new instance creation expression, because you can only assign it to a variable of type Animals (or a superclass), thus preventing the compiler from accessing the specific class methods.


An alternative would be to declare it as a named class.

The most similar to what you have here would be a local class, although they are pretty rarely used (if known about at all), in my experience:

public static void main(String[] args) {
  class Cat extends Animals {
    Cat() { super("Cat"); }

    // ...

    public void color() { ... }
  }

  Cat cat = new Cat();
  cat.color();
}

This is sort-of what the var approach does; it just gives the type an explicit name. This approach would be good if you wanted to create more than one instance of Cat in that method.

But there's not an obvious reason why this would need to be a local class: you could alternatively declare it as a nested or inner class, or, of course, a top-level class.

Andy Turner
  • 137,514
  • 11
  • 162
  • 243
0

You cannot do that.. The first thing is Animals class has no method name Color.

Oseamiya
  • 67
  • 9