Interfaces and Method call- Handling by the JVM

So i was wondering how Something was handled by the jvm so i’ll show you with an example.
So imagine :

Person is an interface

and

Student implements Person

and that somewhere i have

public static final boolean areFriends(Person person1, Person person2){
//Do a lot of stuff to see if they're friends
}
public static final boolean areFriends(Student student1, Student student2){
//Do a single fast check to see if they're friends so using this method is better if the Person is a Student
}

So first : Is is a bad practice ?(Almost sure that’s a bad practice) And how does the jvm handle that and know which method to call ?

From my tests :


Person p1 = new Student();
Person p2 = new Student();
areFriends(p1, p2);

This calls the interface method :areFriends(Person person1, Person person2).


Student p1 = new Student();
Student p2 = new Student();
areFriends(p1, p2);

This calls the Student method : areFriends(Student student1, Student student2).

So my simple guess is that the jvm does handle this by simply using the method for the type of the object stored. But i’d like some more explanations. And a correct way to handle that, a check for instanceof feel like the code is bad designed but i don’t really see any other way.

Java has single-dispatch on the type of the first argument and the method arity.
This is implemented via name mangling. https://www.google.com/search?q=name+mangling+java

Are you asking at the low level?

So this has a name. thank you. Apparently from the what i learned on the wikipedia page. Everything is linked. So it’s the compiler choice to link with every Person object the interface method, and Student object with the student method. I see.

Well in fact from what i have seen about name mangling, i’d like to know how interfaces are stored in the jvm, but not really at the bytecode level.

Why not just have an [icode]isFriends(Person person)[/icode] method in the Person interface? So you could do [icode]student1.isFriends(person1)[/icode] or any other variation as long as both objects implement Person.

You have the former but you’re worried about the latter?! :stuck_out_tongue:

instanceof has its place in a single dispatch language like Java. Don’t overuse it, but don’t overly complicate things just to get rid of it! Particularly don’t worry if it’s a check for a single type - eg. imagine how convoluted implementing equals() could be without type checking. Ideally remove the need for it from your API though -

Have you a reason why isFriend(Person other) isn’t a method of the Person interface? Then the Student implementation would be -


public boolean isFriend(Person other) {
  if (other instanceof Student) {
    Student s = (Student) other;
    // do fast check
  } else {
     // do slow check (assuming Students can be friends with non-students, otherwise return false
  }
}

EDIT : appears @CelestialCreator and I had the same idea at the same time. That’s the problem with celestial creators - they always know what you’re thinking! ;D

Thank you. Yes i had the same idea, that’s why i was tempted to precise hat my question wasn’t about the “code design”, because yes in our example that’s better to add this method in the Person interface. But what if i had hundreds of classes implementing the same Person interface ? I should then write hundreds of calls to the method areFriends(Person, Person) for each Person implementation. So the best way would probably be as you suggested with the instanceof.

Try not use it because think its buggy - by logic)
But not remember to test it ^^
so test


	static public void main(String[] args){
		a a1 = new a();
		a a2 = new a();
		b b1 = new b();
		b b2 = new b();
		a b1_a = b1;
		a b2_a = b2;
		
		f(a1, a2);//a, a 0 0
		f(b1, b2);//b, b 1 1
		f(b1_a, b2_a);//a, a 1 1
		f(b1_a, b2);//a, a 1 1
		f(b1_a, a2);//a, a 1 1
	}
	
	static public void f(a a1, a a2){
		System.out.println("a, a");
		System.out.println(a1.i);
		System.out.println(a1.i);
	}
	
	static public void f(b a1, b a2){
		System.out.println("b, b");
		System.out.println(a1.i);
		System.out.println(a1.i);
	}
	
	static class a{int i = 0;}
	
	static class b extends a{
		public b(){i = 1;}
	}

or like this =)

areFriends_Person(...)
areFriends_Student(...)

as i remember methods parsed to byte code
so when java code parsed - parser take variable in function type
and find for it needed function,
so: no dynamic auto variable top class check)