How to call a method created in an inline class [duplicate] - java

This question already has answers here:
Calling newly defined method from anonymous class
(6 answers)
Closed 1 year ago.
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");
}
}

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.

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

Related

Does static binding really happen for overloaded methods in Java? [duplicate]

I'm currently doing an assignment for one of my classes, and in it, I have to give examples, using Java syntax, of static and dynamic binding.
I understand the basic concept, that static binding happens at compile time and dynamic binding happens at runtime, but I can't figure out how they actually work specifically.
I found an example of static binding online that gives this example:
public static void callEat(Animal animal) {
System.out.println("Animal is eating");
}
public static void callEat(Dog dog) {
System.out.println("Dog is eating");
}
public static void main(String args[])
{
Animal a = new Dog();
callEat(a);
}
And that this would print "animal is eating" because the call to callEat uses static binding, but I'm unsure as to why this is considered static binding.
So far none of the sources I've seen have managed to explain this in a way that I can follow.
From Javarevisited blog post:
Here are a few important differences between static and dynamic binding:
Static binding in Java occurs during compile time while dynamic binding occurs during runtime.
private, final and static methods and variables use static binding and are bonded by compiler while virtual methods are bonded during runtime based upon runtime object.
Static binding uses Type (class in Java) information for binding while dynamic binding uses object to resolve binding.
Overloaded methods are bonded using static binding while overridden methods are bonded using dynamic binding at runtime.
Here is an example which will help you to understand both static and dynamic binding in Java.
Static Binding Example in Java
public class StaticBindingTest {
public static void main(String args[]) {
Collection c = new HashSet();
StaticBindingTest et = new StaticBindingTest();
et.sort(c);
}
//overloaded method takes Collection argument
public Collection sort(Collection c) {
System.out.println("Inside Collection sort method");
return c;
}
//another overloaded method which takes HashSet argument which is sub class
public Collection sort(HashSet hs) {
System.out.println("Inside HashSet sort method");
return hs;
}
}
Output: Inside Collection sort method
Example of Dynamic Binding in Java
public class DynamicBindingTest {
public static void main(String args[]) {
Vehicle vehicle = new Car(); //here Type is vehicle but object will be Car
vehicle.start(); //Car's start called because start() is overridden method
}
}
class Vehicle {
public void start() {
System.out.println("Inside start method of Vehicle");
}
}
class Car extends Vehicle {
#Override
public void start() {
System.out.println("Inside start method of Car");
}
}
Output: Inside start method of Car
Connecting a method call to the method body is known as Binding. As Maulik said "Static binding uses Type(Class in Java) information for binding while Dynamic binding uses Object to resolve binding." So this code :
public class Animal {
void eat() {
System.out.println("animal is eating...");
}
}
class Dog extends Animal {
public static void main(String args[]) {
Animal a = new Dog();
a.eat(); // prints >> dog is eating...
}
#Override
void eat() {
System.out.println("dog is eating...");
}
}
Will produce the result: dog is eating... because it is using the object reference to find which method to use. If we change the above code to this:
class Animal {
static void eat() {
System.out.println("animal is eating...");
}
}
class Dog extends Animal {
public static void main(String args[]) {
Animal a = new Dog();
a.eat(); // prints >> animal is eating...
}
static void eat() {
System.out.println("dog is eating...");
}
}
It will produce : animal is eating... because it is a static method, so it is using Type (in this case Animal) to resolve which static method to call. Beside static methods private and final methods use the same approach.
Well in order to understand how static and dynamic binding actually works? or how they are identified by compiler and JVM?
Let's take below example where Mammal is a parent class which has a method speak() and Human class extends Mammal, overrides the speak() method and then again overloads it with speak(String language).
public class OverridingInternalExample {
private static class Mammal {
public void speak() { System.out.println("ohlllalalalalalaoaoaoa"); }
}
private static class Human extends Mammal {
#Override
public void speak() { System.out.println("Hello"); }
// Valid overload of speak
public void speak(String language) {
if (language.equals("Hindi")) System.out.println("Namaste");
else System.out.println("Hello");
}
#Override
public String toString() { return "Human Class"; }
}
// Code below contains the output and bytecode of the method calls
public static void main(String[] args) {
Mammal anyMammal = new Mammal();
anyMammal.speak(); // Output - ohlllalalalalalaoaoaoa
// 10: invokevirtual #4 // Method org/programming/mitra/exercises/OverridingInternalExample$Mammal.speak:()V
Mammal humanMammal = new Human();
humanMammal.speak(); // Output - Hello
// 23: invokevirtual #4 // Method org/programming/mitra/exercises/OverridingInternalExample$Mammal.speak:()V
Human human = new Human();
human.speak(); // Output - Hello
// 36: invokevirtual #7 // Method org/programming/mitra/exercises/OverridingInternalExample$Human.speak:()V
human.speak("Hindi"); // Output - Namaste
// 42: invokevirtual #9 // Method org/programming/mitra/exercises/OverridingInternalExample$Human.speak:(Ljava/lang/String;)V
}
}
When we compile the above code and try to look at the bytecode using javap -verbose OverridingInternalExample, we can see that compiler generates a constant table where it assigns integer codes to every method call and byte code for the program which I have extracted and included in the program itself (see the comments below every method call)
By looking at above code we can see that the bytecodes of humanMammal.speak(), human.speak() and human.speak("Hindi") are totally different (invokevirtual #4, invokevirtual #7, invokevirtual #9) because the compiler is able to differentiate between them based on the argument list and class reference. Because all of this get resolved at compile time statically that is why Method Overloading is known as Static Polymorphism or Static Binding.
But bytecode for anyMammal.speak() and humanMammal.speak() is same (invokevirtual #4) because according to compiler both methods are called on Mammal reference.
So now the question comes if both method calls have same bytecode then how does JVM know which method to call?
Well, the answer is hidden in the bytecode itself and it is invokevirtual instruction set. JVM uses the invokevirtual instruction to invoke Java equivalent of the C++ virtual methods. In C++ if we want to override one method in another class we need to declare it as virtual, But in Java, all methods are virtual by default because we can override every method in the child class (except private, final and static methods).
In Java, every reference variable holds two hidden pointers
A pointer to a table which again holds methods of the object and a pointer to the Class object. e.g. [speak(), speak(String) Class object]
A pointer to the memory allocated on the heap for that object’s data e.g. values of instance variables.
So all object references indirectly hold a reference to a table which holds all the method references of that object. Java has borrowed this concept from C++ and this table is known as virtual table (vtable).
A vtable is an array like structure which holds virtual method names and their references on array indices. JVM creates only one vtable per class when it loads the class into memory.
So whenever JVM encounter with a invokevirtual instruction set, it checks the vtable of that class for the method reference and invokes the specific method which in our case is the method from a object not the reference.
Because all of this get resolved at runtime only and at runtime JVM gets to know which method to invoke, that is why Method Overriding is known as Dynamic Polymorphism or simply Polymorphism or Dynamic Binding.
You can read it more details on my article How Does JVM Handle Method Overloading and Overriding Internally.
The compiler only knows that the type of "a" is Animal; this happens at compile time, because of which it is called static binding (Method overloading). But if it is dynamic binding then it would call the Dog class method. Here is an example of dynamic binding.
public class DynamicBindingTest {
public static void main(String args[]) {
Animal a= new Dog(); //here Type is Animal but object will be Dog
a.eat(); //Dog's eat called because eat() is overridden method
}
}
class Animal {
public void eat() {
System.out.println("Inside eat method of Animal");
}
}
class Dog extends Animal {
#Override
public void eat() {
System.out.println("Inside eat method of Dog");
}
}
Output:
Inside eat method of Dog
There are three major differences between static and dynamic binding while designing the compilers and how variables and procedures are transferred to the runtime environment.
These differences are as follows:
Static Binding: In static binding three following problems are discussed:
Definition of a procedure
Declaration of a name(variable, etc.)
Scope of the declaration
Dynamic Binding: Three problems that come across in the dynamic binding are as following:
Activation of a procedure
Binding of a name
Lifetime of a binding
With the static method in the parent and child class: Static Binding
public class test1 {
public static void main(String args[]) {
parent pc = new child();
pc.start();
}
}
class parent {
static public void start() {
System.out.println("Inside start method of parent");
}
}
class child extends parent {
static public void start() {
System.out.println("Inside start method of child");
}
}
// Output => Inside start method of parent
Dynamic Binding :
public class test1 {
public static void main(String args[]) {
parent pc = new child();
pc.start();
}
}
class parent {
public void start() {
System.out.println("Inside start method of parent");
}
}
class child extends parent {
public void start() {
System.out.println("Inside start method of child");
}
}
// Output => Inside start method of child
All answers here are correct but i want to add something which is missing.
when you are overriding a static method, it looks like we are overriding it but actually it is not method overriding. Instead it is called method hiding. Static methods cannot be overridden in Java.
Look at below example:
class Animal {
static void eat() {
System.out.println("animal is eating...");
}
}
class Dog extends Animal {
public static void main(String args[]) {
Animal a = new Dog();
a.eat(); // prints >> animal is eating...
}
static void eat() {
System.out.println("dog is eating...");
}
}
In dynamic binding, method is called depending on the type of reference and not the type of object that the reference variable is holding
Here static bindinghappens because method hiding is not a dynamic polymorphism.
If you remove static keyword in front of eat() and make it a non static method then it will show you dynamic polymorphism and not method-hiding.
i found the below link to support my answer:
https://youtu.be/tNgZpn7AeP0
In the case of the static binding type of object determined at the compile-time whereas in
the dynamic binding type of the object is determined at the runtime.
class Dainamic{
void run2(){
System.out.println("dainamic_binding");
}
}
public class StaticDainamicBinding extends Dainamic {
void run(){
System.out.println("static_binding");
}
#Override
void run2() {
super.run2();
}
public static void main(String[] args) {
StaticDainamicBinding st_vs_dai = new StaticDainamicBinding();
st_vs_dai.run();
st_vs_dai.run2();
}
}
Because the compiler knows the binding at compile time. If you invoke a method on an interface, for example, then the compiler can't know and the binding is resolved at runtime because the actual object having a method invoked on it could possible be one of several. Therefore that is runtime or dynamic binding.
Your invocation is bound to the Animal class at compile time because you've specified the type. If you passed that variable into another method somewhere else, noone would know (apart from you because you wrote it) what actual class it would be. The only clue is the declared type of Animal.

Is it possible to access objects from another class without parameters

Is it possible to access an object created in one class from another class without using parameters/arguments?
For example:
public class Main {
public static void main(String[] args) {
Two make = new Two(); // Object I created.
make.ham();
}
}
class Two {
public void ham() {
System.out.println("Ham.");
}
}
class Three {
public static void accessObject() {
// Can I access the object make here without parameters?
}
}
What I understood is that you want to access to make object, created inside Main class (Two make = new Two());. And yes, it's possible to do it.
You have to create your variable make as global and static (and it's recommended be public or protected, in case you have your classes in separate files).
So, inside your Main class, you will have to do something like:
public class Main {
public static Two make;
public static void main(String[] args) {
make = new Two(); // Object I created.
make.ham();
Three.accessObject();
}
}
As you can see, I created the make variable as static and global. This is necessary because your main method is static, and it's global to be able to be recognized by other classes. And to can call to accessObject method, I did it with the class name (because that method is static)(Three.accessObject();)
And finally inside your Three class, in the accessObject method it's necessary call to the static variable make from Main class:
class Three {
public static void accessObject() {
System.out.println("using make object from Main class in Three class...");
Main.make.ham();
}
}
As you can see now, I called the variable make with the name class Main because it's static, and finally, you will be able to call the ham method by this way.
You could you inheritance to solve your problem. For example, you would write:
class Three extends Two {
public static void accessObject() {
// You can now access the "Two" object since you have now made
// Three a subclass of Two.
}
}
EDIT:
If you wanted to say, change the implementation of the ham() method, you could do something like this:
class Two {
public void ham() {
System.out.println("Ham.");
}
}
class Three extends Two {
#Override
public void ham() {
System.out.println("I'm inside ham, but inside the Three class.);
}
}

Why is this typecasted variable calling function of subclass?

I have four classes below.
Class Note:
public class Note {
Pitch primaryPitch = new Pitch();
static Pitch secondaryPitch = new Pitch();
Note() {
System.out.println("Tune()");
}
static void pitch() {
System.out.println("Note.pitch()");
}
void volume() {
System.out.println("Note.volume()");
}
}
Class Tune:
public class Tune extends Note{
Tune() {
System.out.println("Tune()");
}
static void pitch() {
System.out.println("Tune.pitch()");
}
void volume() {
System.out.println("Tune.volume()");
}
void rhythm()
{
Note note = (Note) this;
note.volume();
}
}
Class Song:
public class Song extends Tune{
void volume() {
System.out.println("Song.volume()");
}
}
Class Test:
public class Test {
public static void main(String[] args) {
Note note2 = new Song();
((Tune)note2).rhythm();
}
When I run main, I expect the output Note.volume(). The reason I expect that output is because in the Tune class, when I call note.volume();, note has been typecast to a Note object, so I expect to use the Note class volume() method call. Instead I get Song.volume() which means I am using the Song class volume() method call.
My question is, why do I get Song.volume() and not note.volume();?
Because note is an object of type Song(). The fact that you cast it to a parent type does not change the polymorphic behavior of the volume() method. This is evident if you run the code in your IDE, and in Tune.Rhythm(), look at the variable values:
this means current instance Song, even you cast to Note, it's still Song instance
by the way, In the runtime, Java doesn't have type, so cast in the runtime is meaningless. cast is just fro Compiler to infer type by context.
Since Song also extends from Note by extends from Tune,
and Override volume method, so this.volume() will invoke the Override Song.volume method.
And if need to call the parent class Note.volume, need to use super with volume method, like: super.volume().

Create a dynamic class in java

I'm working on a problem where different animal types implement the same talk() method from Animal interface.
If you look at getAnimal() method, you can see that, when a new kind of animal is added to the program, inside of that method has to be changed as well.
I want to add new animals just by subclassing Animal without changing anything in the already existing classes.
For example, add an animal "Dog", criteria="loyal"; talk="woof".
Could you tell me, how it is possible? Below is my code:
interface Animal {
public void talk();
}
class Lion implements Animal {
#Override
public void talk() {
System.out.println("ROARRRRR");
}
}
class Mouse implements Animal {
#Override
public void talk() {
System.out.println("SQUEEEEEAK");
}
}
class Bison implements Animal {
#Override
public void talk() {
System.out.println("BELLOWWWWW");
}
}
class AnimalType {
public static Animal getAnimal(String criteria) {
// I refactor this method
if (criteria.equals("small")) {
return new Mouse();
} else if (criteria.equals("big")) {
return new Bison();
} else if (criteria.equals("lazy")) {
return new Lion();
}
return null;
}
}
public class AnimalExamples {
public static void main(String[] args) {
AnimalType.getAnimal("small").talk();
AnimalType.getAnimal("big").talk();
AnimalType.getAnimal("lazy").talk();
// how to add an animal "Dog" here, criteria="loyal"; talk="woof"
AnimalType.getAnimal("loyal").talk();
try {
AnimalType.getAnimal("small").talk();
} catch (Exception ex) {
System.out.println("Animal does not exists");
}
}
}
I searched on google, understood it can be done by reflection. But do not know how. If possible, could you help me with this, please? Thanks in advance!
Just so you know runtime class generation is extremely complex and not something recommended for beginners to the language. This would be an excellent scenario to use a map an anonymous classes.
class AnimalType {
private static final Map<String, Animal> animals = new HashMap<String, Animal>();
static {
// Populating map with default animals
addAnimal("big","BELLOWWWWW"); // bison
addAnimal("small","SQUEEEEEAK"); // mouse
addAnimal("lazy","ROARRRRR"); // lion
addAnimal("loyal","WOOF "); // dog
}
public static void addAnimal(String criteria, final String sound) {
// Assigning a anonymous implementation of animal to the given criteria
animals.put(criteria, new Animal() {
#Override
public void talk() {
System.out.println(sound);
}
});
}
public static Animal getAnimal(String criteria) {
// Returning an animal from the animals map
return animals.get(criteria);
}
}
If you really do insist on true runtime class generation or if you're curious how it works, check out ByteBuddy.
Old question, but here is how to create class... For me the easy way is to use Javassist.
I created a small example here: http://hrabosch.com/2018/04/08/generate-class-during-runtime-with-javassist/
But here is main point:
public static Class generateClass(String className, String methodName, String methodBody)
throws CannotCompileException {
ClassPool pool = ClassPool.getDefault();
CtClass cc = pool.makeClass(className);
StringBuffer method = new StringBuffer();
method.append("public void ")
.append(methodName)
.append("() {")
.append(methodBody)
.append(";}");
cc.addMethod(CtMethod.make(method.toString(), cc));
return cc.toClass();
}
So what I did... Via Javassist I made a class in ClassPool. Also I added a method inside this class and via reflection I invoked it.
Hope it helps.
Just keep on mind whatever you want to use in generated class, there
are NOT imports, so you have to use fully-qualified names.
Java doesn't support creating a class at runtime. However there are really better ways of achieving what you want here. I'll propose two.
Firstly, you could create an AnimalType class that contains all the shared behaviour about a species. You could then have an Animal class that takes an AnimalType as a constructor parameter.
Secondly, you could use a prototype design pattern. In this case the Animal class would need a clone method to create a new animal from the prototype. The factory class could then have a list of the prototypes and use whatever logic you desire to choose the correct prototype to clone.
Comment below if you want further details or sample code for either of these options.
you have to define the dog class
class Dog implements Animal {
#Override
public void talk() {
System.out.println("woof");
}
}
and add the if else to AnimalType
} else if ("loyal".equals(criteria)) {
return new Dog();
}

What is the VB "Shadow" or C# "new" keyword Equivalent in Java?

When I want to define a new implementation of a non virtual method, then I could to use new keyword in C# or shadow keyword in VB. For example:
C# code:
public class Animal
{
public void MyMethod()
{
//Do some thing
}
}
public class Cat : Animal
{
public new void MyMethod()
{
//Do some other thing
}
}
VB code:
Public Class Animal
Public Sub MyMethod()
'Do some thing
End Sub
End Class
Public Class Cat
Inherits Animal
Public Shadows Sub MyMethod()
'Do some other thing
End Sub
End Class
Now, my question is:
What is the VB Shadow (or C# new) keyword equivalent in Java ?
The primary answer to your question is probably "There is none." Details:
Java's methods are "virtual" (in C# terminology) by default; they can be overridden in subclasses. No special keyword is required on the original method. When defining the override, it's useful (but not required) to use the #Override annotation so that the compiler will warn you if you're not overriding when you think you are, and so people reading the code (and JavaDoc) know what you're doing.
E.g.:
class Parent {
public void method() {
}
}
class Child extends Parent {
#Override
public void method() {
}
}
Note that there's no special keyword on method in Parent.
If a Java method is marked final (non-virtual, the C# default), you can't override it at all. There is no equivalent to C#'s new in that context. E.g.:
class Parent {
public final void method() {
}
}
class Child extends Parent {
#Override // <== Won't compile, you simply can't override
public void method() { // <== final methods at all (even if you added
// <== "final" to the declaration)
}
}

Categories