is it possible to get the class of the interface <Set> - java

Am having some arguments say (String a, Treeset b, Set c)
and I try to get the class by arguments[i].getClass(); of the above arguments..
is Iit possible to get the class of the interface <Set>.
For example:
Class[] argumentTypes = new Class [arguments.length];
for (int i = 0 ; i < arguments.length ; i++)
{
argumentTypes[i] = arguments[i].getClass();
}

The code you've given will find the classes of the arguments (i.e. the values provided to the method) - but those can never be interfaces; they'll always be concrete implementations. (You can never pass "just a set" - always a reference to an object which is an instance of an implementation of the interface, or a null reference.)
It sounds like you want the types of the parameters - which you'd get via reflection if you absolutely had to, finding the Method and then getting the parameters from that with getParameterTypes. But given that you're within the method, you already know the parameter types, because they're at the top of the method... I'm not sure the best way of finding "the currently executing" method, if that's what you're after.
If you're just trying to get the class associated with Set, you can use Set.class of course. But again, it's not really clear what you're trying to do.
EDIT: Okay, judging from your comment, there are some logical problems with what you're trying to do. Going from the values of arguments to which method would be invoked is impossible in the general case, because you've lost information. Consider this, for example:
void foo(String x) {}
void foo(Object y) {}
foo("hello"); // Calls first method
foo((Object) "hello"); // Calls second method
Here the argument values are the same - but the expressions have a different type.
You can find all methods which would be valid for the argument values - modulo generic information lost by type erasure - using Class.isAssignableFrom. Does that help you enough?
Note that you'll also need to think carefully about how you handle null argument values, which would obviously be valid for any reference type parameter...

You can use http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Class.html#getInterfaces()

You will get the class what the caller provided.
I mean,in below class you will get HashSet.
Set set=new HashSet();
System.out.println(set.getClass());

You can do this in two ways given below
Set s = new //any class that implements it for example HashSet or TreeSet etc.;
s.getClass().getName(); //This will return the name of the subclass which is refered by s.
or if in other way can do it
Set s = null;
s.getClass();//This causes NullPointer Exception

Related

Accessing a variable within a passed object

I'm having issues with a concept from an assignment I'm working on
public class MyHugeInteger
{
MyIntList list = new MyIntList();
public int compareTo(MyHugeInteger hugeInt)
{
if (list.size() > this.list.size()) //this is where things don't work
return (-1);
if (list.size() < this.list.size())
return (1);
}
Basically, I need to be able to use the 'list' variable from the passed version of the object to be able to compare it to the list variable from the current object.
I had a similar problem to this before, and my professor responded with "objects of the same class can access each others' private data members. So you do have access to other.size from "this" and can check Set sizes for equality."
This is what I'm trying to use in the code given, but I found an example saying that this will call the field variable, the one already called by just saying 'list'
Am I missing something?
The comment was right, hugeInt.list.size() > this.list.size() instead of using 'this' for the passed object. One of those things that you miss when you're overthinking the problem
If you're trying to use the Java framework to sort things or use the compareTo method, as intended, you need to implements Comparable<MyHugeInteger> in your class.
public class MyHugeInteger implements Comparable<MyHugeInteger>
Then, to fix the error, you need to use the parameter object because this.list and the unqualified list are the exact same object.
Also consider what happens when sizes are equal.
Tip: don't need to rewrite the integer comparison logic yourself.
#Override
public int compareTo(MyHugeInteger hugeInt) {
return Integer.compare(this.list.size(), hugeInt.list.size());
}
Multiply by negative one or flip the parameters if you notice the ordering is wrong.

Generic type in getConstructors() in Class

In the generic class Class<T> the method getConstructors() has a return type with unknown generic type parameter instead of T. The reason for this is explainend in the javadoc.
Note that while this method returns an array of Constructor<T> objects (that is an array of constructors from this class), the return type of this method is Constructor<?>[] and not Constructor<T>[] as might be expected. This less informative return type is necessary since after being returned from this method, the array could be modified to hold Constructor objects for different classes, which would violate the type guarantees of Constructor<T>[].
A colleague of mine and I have tried to understand that explanation. In our understanding they are basically saying that it is of unknown generic type, because some caller could put other Constructor objects into that array. Did we get that right? And if so, why would someone design an API this way. Wouldn't it be better to use the specific type and trust the programmer to use the array correctly? To us it sounds a little like "We are making a worse API because the programmer using it might try something stupid". Where lies our fallacy?
The point that was mentioned by Ashu Pachauri in the comment (namely, that the array is returned for backward compatibility) is certainly valid. And in general, arrays and generics don't play together very well. (For evidence, look for all the stackoverflow questions related to "Generic Arrays"...)
Additionally, there is a rule that an API should be easy to use and hard to misuse. In this case, this is related to the Principle of least astonishment: Someone obtaining the constructors with this method could perform a perfectly legal sequence of operations on the returned array, and in the end, receive an unexpected ClassCastException. So one could say that the fact that a Constructor<?>[] array is returned aims at a "fail-fast" behavior.
An illustrative example:
import java.lang.reflect.Constructor;
public class GetConstructorsReturnType
{
public static void main(String[] args) throws Exception
{
// This causes a warning, due to the cast, but imagine
// this was possible
Constructor<DerivedA> constructorsA[] =
(Constructor<DerivedA>[])DerivedA.class.getConstructors();
// The following lines are valid due to the subtype
// relationship, but would not be valid if constructorsA
// was declared as "Constructor<?>"
Constructor<? extends Base> constructors[] = constructorsA;
constructors[0] = DerivedB.class.getConstructor();
// This causes a ClassCastException (and would also not
// be possible constructorsA was declared as "Constructor<?>"
DerivedA instance = constructorsA[0].newInstance();
}
}
class Base
{
}
class DerivedA extends Base
{
public DerivedA()
{
}
}
class DerivedB extends Base
{
public DerivedB()
{
}
}
It's the exact same reason why you are not allowed to do new Constructor<T>[], but you are allowed to do new Constructor<?>[]. You can apply your same argument and say "Wouldn't it be better to use the allow the specific type and trust the programmer to use the array correctly?" Well, Java decided no. (You can imagine that inside the getConstrucotrs method, they need to create an array of Constructor, and they cannot do new Constructor<T>[] but they can do new Constructor<?>[].)
Of course, you can make an unchecked cast of the Constructor<?>[] to the Constructor<T>[], but that will give you a warning in your code, in which case you would take responsibility for making sure it's safe. But if the getConstructors method this this unchecked cast in their code, you as the caller would never be warned about the unsafeness.

Why can't I use .pollFirst() method for a Set that was initialized as a TreeSet?

Say I've intialized a Set as a new TreeSet:
Set<Integer> foo = new TreeSet<Integer>();
And I want to use the .pollFirst() method, because I'm lazy and I don't want to have to use a temp variable because I have this handy method that would reduce what would otherwise be 3-4 lines of code to 1 line.
However, with the following code, the only way to compile my code would be to specifically call foo a TreeSet.
while (foo.size() > 1) {
int lower = foo.pollFirst();
int higher = foo.pollFirst();
foo.add(higher - lower);
}
So why java doesn't realize that foo is actually a TreeSet? Should I just cast it as TreeSet if I didn't want to intialize foo as a TreeSet? Or would it be better to just intialize it that way?
Further Testing with Casting:
while (foo.size() > 1) {
int lower = (int) ((TreeSet) foo).pollFirst();
int higher = (int) ((TreeSet) foo).pollFirst();
foo.add(higher - lower);
}
This makes it compile without explicitly calling it a TreeSet upon intialization.
That's because Set doesn't define a pollFirst() method, it is defined by NavigableSet, which is implemented by TreeSet. On the other hand, to answer your question, one good reason I can think of for java to behave like that, is this, assume that later in your code you do something like this,
Set<Integer> foo = new TreeSet<Integer>();
...
foo = ExternalLibraryClass.getUnknownSetImplementation();
// At this point, how would the compiler know what 'foo' actually is?
where ExternalLibraryClass is an arbitrary class from an arbitrary library and getUnknownSetImplementation() is an arbitrary method that returns a Set implementation. The important thing is that your compiler does NOT have access to the library's source code, therefore it does NOT know what Set implementation will be returned every time getUnknownSetImplementation() gets called.
SOME MORE ILLUSTRATION
Assume,
String whichSet = externalWebService.whichSetShouldIUse();
if(whichSet.equals("HashSet"))
foo = new HashSet()<>;
else if(whichSet.equals("TreeSet"))
foo = new TreeSet()<>;
// At this point, how would the compiler know what 'foo' actually is?
The Short Answer
This is because that Set doesn't define the pollFirst() or pollLast() methods. You may check the Set Interface documentation here and the TreeSet Class documentation here to verify this.
The Long Answer
The reason why this happens is because of Inheritance. The child class inherits members from the parent class, but the parent class won't have any idea of its children's members. Now in the Collection framework in Java, the Set interface is the parent of the TreeSet class.
As a result, when we use a Set reference to initialize a TreeSet object, we miss out on the member functions specifically written for TreeSet (which is pollFirst() in your case). However common member functions(first(), last()) to both of them work fine without any issues.
Example
In the examples here and here TreeSet reference is used for declaration, thus it works without any problem.

super of sub function

I have a function in my superclass (Speler) that is called kiesKaart:
public Kaart kiesKaart(int spelerIndex){...}
In my subclass function, I have the same function with an other parameter that overrides (i do have #Override before it, changing this to #Override() does not help...) the super function:
public int kiesKaart(Kaart lak){...}
In my main I have an array of Spelers, where only the first is an Speler and the others are AiSpelers (this is the name of the subclass):
spelerArr[0] = new Speler(hand[0]);
for (int i=1;i<AANTALSPELERS;i++) {
spelerArr[i] = new AiSpeler(hand[i]);
}
Later on in my code I address spelerArr[i].kiesKaart, so now I want the code to address the correct instance of kiesKaart.
How can I do this?
The signatures do not match. So you are not overriding the method in super class. The compiler will complain if you use #Override. The signature of the method also includes the type of the parameter.
You overloaded the method by creating a new one with the same name and different arguments. Override is a different thing.
Using #Override will do nothing here because the two methods are different. The first one returns type Kaart given an int, and the second returns type int given a Kaart.
In other words, to make sure you are calling the right method, you need to make sure you send the right parameter (int for the first, Kaart for the second).
I believe you are going to have to use instanceof to determine if it is a Speler or AiSpeler and cast it to the appropriate object before calling kiesKaart.
You are overloading your superclass method, not overriding. Having an annotation does not change this fact.
If you want to determine the type of the calling object (polymorphism) you have to override the method - same parameter list, same return type or a subclass (as of Java 5) and of course the same name.
This might be helpful as a quick reference on what is possible and what not, and how to call it

Why method is not called according to data type , if the value needs to be stored in a variable

The following java code will not execute.
class A{
int sqrt(int a)
{
}
float sqrt(int a)
{
}
int a1 = sqrt(a);
float b1= sqrt(b);
}
In interview i was asked by a question that why java compiler does not check the data type and call that method accordingly. What is the reason?
Those methods have the same signature (identifier + parameter list), which is illegal.
The reason the compiler won't allow this is that it is not always possible to infer the desired data type. For example, Java supports "boxing" of native values into objects, so you should be able to do this:
ArrayList<Object> list = new ArrayList<Object>();
list.add(a.sqrt(4));
In code like this, it would be literally impossible for the compiler to figure out whether you wanted to call the method that returns a float or the method that returns an int.
If you have 2 methods with same name and same parameters of same data types then java compiler will not even let you compile the code. It should say that method "sqrt" is already defined. So it's illegal in java.
I asked when i was a beginner in programming. . Let me give the answer myself. It always checks the return type of method and call that method accordingly . In case of
int a1 = sqrt(a);
it will call method whose return type is integer.

Categories