When I run the following code:
class zTree<T>
{
ArrayList<ArrayList<T>> table = new ArrayList<ArrayList<T>>();
int height = 0;
<T> void zTree(BinaryTree<T> tree)
{
recIt((BinaryTree<T>)tree, 1);
}
void recIt(BinaryTree<T> tree, int fromRoot)
{
if(!(tree.isEmpty()))
{
ArrayList<T> tempList = (ArrayList<T>)table.get(fromRoot);
tempList.add((T)tree.getData()); // add data to table
recIt(tree.left,fromRoot+1); // recursive left,
recIt(tree.right,fromRoot+1); // right
}
else
{
height = fromRoot-1;
}
}
}
Javac returns this error.
zTree.java:15: recIt(structures.tree.BinaryTree<T>,int) in zTree<T> cannot be applied to (structures.tree.BinaryTree<T>,int)
recIt((BinaryTree<T>)tree, 1);
^
1 error
I don't care about he efficiency of my code. I care to understand what is going wrong but javac is clearly not much help for once as it's telling me that (x,y) can not be applied to (x,y) ... but why?
The problem is that the T in the zTree method (which bizarrely has the same name as its enclosing class - don't do that) isn't the same as the T in the zTree class, because the method is generic:
<T> void zTree(BinaryTree<T> tree)
If you make it not generic, it should be fine, as now the T type parameter within the method will mean the same as the T in the method you're calling.
void zTree(BinaryTree<T> tree)
I would strongly advise use to start following Java naming conventions, and definitely don't create any methods with the same name as the class in which they're declared.
If that method was meant to be a constructor, you should get rid of the return type:
zTree(BinaryTree<T> tree)
(And still fix the class name.)
You are declare the method zTree generic when you say
<T> void zTree(BinaryTree<T> tree)
I suspect that you wanted to create a constructor. If so, don't use a return type. However, you've already declared your class generic; just use your class's T:
zTree(BinaryTree<T> tree)
Additionally, conventionally, Java class names start with an uppercase letter, e.g. ZTree.
Related
In java, how is a child object constructed?
I just started inheritance and these few points are not very clear to me:
Does the child object depend only on the child class' constructor, or does it also depend on the parent's constructor? I need some details about that point.
Also, is super() always called by default in a child constructor?
Any other information regarding this topic is appreciated.
I don't think "A child object" is a good way to think about this.
You're making an object. Like all objects, it is an instance of some specific class, (After all, new SomeInterface() does not compile) and like (almost) all objects, it is made because some code someplace (doesn't have to be your code, of course) ran the java expression new SomeSpecificClass(args); somewhere.
We could say it is a 'child object' because SomeSpecificClass is a child class of some other class.
But that's rather useless. That means the only way to ever make a new 'non-child' object would be to write new Object(); - after all, all classes except java.lang.Object are a child class: If you write public class Foo {}, java will interpret that exactly the same as if you had written public class Foo extends java.lang.Object {}, after all.
So, barring useless* irrelevancies, all objects are child objects, and therefore as a term, 'child object', I'd not use that.
That also means that ALL object creation goes through this 'okay and in what order and how do the constructors work' song and dance routine.
How it works is probably most easily explained by desugaring it all. Javac (the compiler) injects things if you choose to omit them, because a lot of things that feel optional (such as a constructor, a super call, or an extend clause), at the class file / JVM level, aren't**.
Sugar #1 - extends clause
Already covered: if you have no extends clause on your class def, javac injects extends java.lang.Object for you.
Sugar #2 - no super call in constructor
A constructor must either call some specific super constructor on its very first line, or, it it must call some other constructor from the same class on its very first line (this(arg1, arg2);). If you don't, java will inject it for you:
public MyClass(String arg) { this.arg = arg; }
// is treated as:
public MyClass(String arg) {
super();
this.arg = arg;
}
Notably including a compiler error if your parent class has no zero-arg constructor available.
Sugar #3: No constructor
If you write a class that has no constructor, then java makes one for you:
public YourClass() {}
It will be public, it will have no args, and it will have no code on it. However, as per sugar #2 rule, this then gets expanded even further, to:
public YourClass() {super();}
Field inits and code blocks get rewritten to a single block.
The constructor isn't the only thing that runs when you make new objects. Imagine this code:
public class Example {
private final long now = System.currentTimeMillis();
}
This code works; you can compile it. You can make new instances of Example, and the now field will hold the time as it was when you invoked new Example(). So how does that work? That feels a lot like constructor code, no?
Well, this is how it works: Go through the source file top to bottom and find every non-static initializing code you can find:
public class Example {
int x = foo(); // all non-constant initial values count
{
x = 10;
// this bizarre constructor is legal java, and also
// counts as an initializer.
}
}
and then move all that over to the one and only initializer that classes get, in the order you saw them.
Ordering
So, via sugar rules we have reduced ALL classes to adhere to the following rules:
ALL classes have a parent class.
ALL classes have at least 1 constructor.
ALL constructors invoke either another constructor or a constructor from parent.
There is one 'initializer' code block.
Now the only question is, in what order are things executed?
The answer is crazy. Hold on to your hats.
This is the order:
First, set all fields to 0/false/null of the entire 'construct' (the construct involves every field from Child all the way down to Object, of course).
Start with the actual constructor invoked on Child. Run it directly, which means, start with the first line, which neccessarily is either a this() or a super() invocation.
Evaluate the entire line, notably, evaluate all expressions passed as arguments. Even if those are themselves invocations of other methods. But, javac will do some minor effort to try to prevent you from accessing your fields (because those are all uninitialized! I haven't mentioned initializers yet!!).
Yeah, really. This means this:
public class Example {
private final long x = System.currentTimeMillis();
public Example() {
super(x); // x will be .... 0
// how's that for 'final'?
}
}
This will either end up invoking the first line of some other constructor of yours (which is itself also either a this() or a super() call). Either we never get out of this forest and a stack overflow error aborts our attempt to create this object (because we have a loop of constructors that endlessly invoke each other), or, at some point, we run into a super() call, which means we now go to our parent class and repeat this entire song and dance routine once more.
We keep going, all the way to java.lang.Object, which by way of hardcoding, has no this() or super() call at all and is the only one that does.
Then, we stop first. Now the job is to run the rest of the code in the constructor of j.l.Object, but first, we run Object's initializer.
Then, object's constructor runs all the rest of the code in it.
Then, Parent's initializer is run. And then the rest of the parent constructor that was used. and if parent has been shifting sideways (this() invokes in its constructors), those are all run in reverse order as normal in method invocations.
We finally end up at Child; its initializer runs, then the constructor(s) run in order, and finally we're done.
Show me!
class Parent {
/* some utility methods so we can run this stuff */
static int print(String in) {
System.out.println("#" + in);
return 0;
// we use this to observe the flow.
// as this is a static method it has no bearing on constructor calls.
}
public static void main(String[] args) {
new Child(1, 2);
}
/* actual relevant code follows */
Parent(int arg) {
print("Parent-ctr");
print("the result of getNow: " + getNow());
}
int y = print("Parent-init");
long getNow() { return 10; }
}
class Child extends Parent {
Child(int a, int b) {
this(print("Child-ctr1-firstline"));
print("Child-ctr1-secondline");
}
int x = print("Child-init");
Child(int a) {
super(print("Child-ctr2-firstline"));
print("Child-ctr2-secondline");
}
final long now = System.currentTimeMillis();
#Override long getNow() { return now; }
}
and now for the great puzzler. Apply the above rules and try to figure out what this will print.
#Child-ctr1-firstline
#Child-ctr2-firstline
#Parent-init
#Parent-ctr
#the result of getNow: 0
#Child-init
#Child-ctr2-secondline
#Child-ctr1-secondline
Constructor execution ordering is effectively: the first line goes first, and the rest goes last.
a final field was 0, even though it seems like it should never be 0.
You always end up running your parent's constructor.
--
*) You can use them for locks or sentinel pointer values. Let's say 'mostly useless'.
**) You can hack a class file so that it describes a class without a parent class (not even j.l.Object); that's how java.lang.Object's class file works. But you can't make javac make this, you'd have to hack it together, and such a thing would be quite crazy and has no real useful purpose.
In inheritance, the construction of a child object depends on at least one parent constructor.
Calling the super () method is not mandatory. By default, Java will call the parent constructor without argument except if you precise a custom constructor.
Here an example
Mother
public class Mother {
int a;
public Mother() {
System.out.println("Mother without argument");
a = 1;
}
public Mother(int a) {
System.out.println("Mother with argument");
this.a = a;
}
}
child
public class Child extends Mother {
public Child() {
System.out.println("Child without argument");
}
public Child(int a) {
super(a);
System.out.println("Child with argument");
}
}
If you do this :
Child c1 = new Child();
you will get :
Mother without argument
Child without argument
If you do this :
Child c1 = new Child(a);
You will get :
Mother with argument
Child with argument
But if you change the second child constructor to and remove the super(arg) the parent constructor without argument will be called :
public Child(int a) {
// super(a);
System.out.println("Child with argument");
}
You will get :
Mother without argument
Child with argument
May be this course for beginners can help you Coursera java inheritance
I'm trying to run a code. i and i get two compilation errors:
1.Reference to System.out.println is ambiguous (conflict between method that gets char[] and a method that gets a String)
2.Cap#1 can't converted to T return st.pop()
import java.util.*;
public class Test
{
public static void main(String[] args)
{
Stack <Number> stackNumber = new Stack<Number>();
Test t = new Test();
t.setMethod(stackNumber,new Integer(3));
System.out.println(t.getMethod(stackNumber));
}
public <T extends Number> void setMethod (Stack<? super Number>st,T t)
{
st.add(t);
}
public <T>T getMethod (Stack<? extends Number >st)
{
return st.pop();
}
}
I know that i can change getMethod signature to return Number and program will be compiled successfully but i want to understand why with current signature i'm getting compilation errors?
AFAIK, T without bounds considered as Object and a function that declares to return Object can return any Object since Object is the "Father" of all classes (including Number). Can someone me what i'm dismissing here?
Neither of your methods should be using wildcard captures, you have two methods that are generic against some T. Like,
public <T> void setMethod(Stack<T> st, T t) {
st.add(t);
}
public <T> T getMethod(Stack<T> st) {
return st.pop();
}
If you want to ensure that T must be a Number for some reason (I would just use Number then), you define it at T. Like,
public <T extends Number> void setMethod(Stack<T> st, T t) {
st.add(t);
}
public <T extends Number> T getMethod(Stack<T> st) {
return st.pop();
}
but i want to understand why with current signature i'm getting compilation errors?
The errors are both because <T> is determined at the call site.
Looking at compilation error 1:
Java selects the most specifically-applicable method. Any of the PrintStream.println methods that take a reference-typed parameter could be selected.
From JLS 15.12.2.5:
The informal intuition is that one method is more specific than another if any invocation handled by the first method could be passed on to the other one without a compile-time error.
Anything that you can pass to println(char[]) or println(String) can also be passed to println(Object), therefore the former methods are more specific than the latter. As such, these will be selected in preference to println(Object).
However, some things that can be passed to println(char[]) cannot be passed to println(String), therefore neither of those is more specific than the other, hence the ambiguous method call.
Now looking at compilation error 2:
public <T>T getMethod (Stack<? extends Number >st)
{
return st.pop();
}
This method must be safe to invoke in all situations. You invoke it like this:
System.out.println(t.getMethod(stackNumber));
i.e. you treat the result simply like an object. But you could, legally, write this at the call site:
String s = t.getMethod(stackNumber);
It's hopefully clear that this would fail, because something popped out of a stack containing numbers can't be cast to a String.
Because the compiler can't guarantee that it will be called with a "safe" T, it's an error.
I am trying to make a SkipList and I have a method that takes a generic data type:
public void add(E key, Integer value)
{
Node<E> p;
p = find(key);
}
Which takes you here:
public Node<E> find(E key)
{
//Start at head
Node<E> p = head;
while (true)
{
while ( (p.getRight().getKey() != Node.posInf) && (p.getRight().getKey().compareTo(key) <= 0 ))
{
p.setRight(p.getRight());
}
//More stuff down here
}
}
The problem is on the compareTo() method. It says the compareTo() method is undefined for type E. In Eclipse it wants me to add two typecasts like this:
((String) p.getRight().getKey().compareTo((String) key) <= 0 )
Why does it want String? The data type could be anything. I tried doing typecast of E instead but Eclipse wants to change it back to String. Any help would be appreciated.
You haven't shown how E is defined, but the error message indicates that you didn't place an upper bound of Comparable<E> on the declaration of E.
You can accomplish that with something like this on your class:
public class SkipList<E extends Comparable<E>>
This will allow you to call compareTo on your key variable of type E.
As to why Eclipse is suggesting casting to a String, it looks like Eclipse is guessing as to what would be the best change to make to make it compile. It may have guessed String because it's Comparable<String>. In this case, it's wrong, because E isn't necessarily a String. The solution here is different, as I stated above: restrict E to be Comparable<E>.
The method compareTo is defined in the interface java.lang.Comparable. There is nothing in your code that tells the compiler that the type parameter E is Comparable. You can do this in the generic type declaration:
class Node<E extends Comparable<E>> {
...
}
By default if you don't declare extends Comparable, you can only access methods defined in the java.lang.Object class.
So, good ol' Dietel states, "All generic method declarations have a type-parameter section delimited by angle brackets (< and >) that precedes the methods return type," (Deitel, 2012, italicized emphasis mine). The example given is as follows:
public static < T > void printArray (T[] inputArray)
{
for (T element : inputArray)
(
System.out.printlf("%s", element);
}
That makes sense to me. I get that. But, here is my question, not addressed explicitly in the book.
I have a very simple class to demonstrate:
public class Pair<F, S>
{
private F first;
private S second;
}
Now, according to Deitel, "ALL" generic method declarations must contain a type-parameter section. So, naturally, I want to add a get() and set() method to my class example. So, I do this:
public class Pair<F, S>
{
private F first;
private S second;
// Here, I'll do one instead of both for the sake of shortening the code
public < F > F getF()
{
return F;
}
// And the Accessor:
public < F > void setF(F first)
{
this.first = first;
}
}
So, here's the deal. The Eclipse IDE gives me a warning ahead of my attempt to compile (the Java version of Intellisense) that states, "The type parameter F is hiding the type F". Now, I don't particularly trust Dietel for Java - and am growing to understand that they are not particularly reliable (in that they often leave out important distinctions). So, I went to the Oracle Documentation for what I am doing and - GUESS WHAT - they mention nothing of the sort, unless you're talking about 'upperbounded' type parameters.
Here's the question (it's threefold):
Is the difference here the `static' qualifier, i.e. that the method I am writing appears in a class?
What on Earth is Dietel doing, particularly as implementation of their suggestions, here, yields a warning?
By changing the class type parameters, I get rid of the warning. So, conceptually, what is going on to where the method parameter type is "hiding" the class parameter type?
The JLS specifically designates a generic method as one that declares type parameters. (JLS) So the confusion here is that Deital has said that "all generic methods have a type parameter section" but presumably not specifically pointed out that this is their definition. It is more clear to say that "a generic method is one that has a type parameter section".
As noted in a comment, when you have type parameters declared by a class, you do not need to redeclare them at the method. As noted by Eclipse, doing so actually declares new type parameters which hide the ones declared by the class.
When they are declared on the class you can use them directly:
class Pair<F, S> {
F getF() { ... }
S getS() { ... }
void setF(F f) { ... }
void setS(S s) { ... }
}
The purpose of a generic method is to use it parametrically. The given example is not particularly good for understanding because the generic type is actually unused: the printf overload for Object is called. It can be rewritten without generics with no change to its functionality:
public static void printArray(Object[] arr) {
for(Object o : arr) {
System.out.printf("%s", o);
}
}
The easiest example for understanding the use of a generic method is the implementation of Objects#requireNonNull which is something like this:
public static <T> T requireNonNull(T obj) {
if(obj == null)
throw new NullPointerException();
return obj;
}
It takes any object and conveniently returns it as a T:
// T is inferred
String hello = Objects.requireNonNull("hello world");
// T is provided as a witness (rarely necessary)
Integer five = Objects.<Integer>requireNonNull(5);
It is the simplest generic method.
"When you declare a type parameter for the class, you can simply use that type any place that you'd use a real class or interface type. The type declared in the method argument is essentially replaced with the type you use when you instantiate the class.
If the class itself doesn't use a type parameter, you can still specify one for a method, by declaring it in a really unusual (but available) space-before the return type, This method says that T can be "any type of Animal"."
Can you explain?
What it means is that in a generic class, you can write methods like so:
public T doSomething () {
}
Note that the return type is 'T'.
At compile-time, the return type of that method will be whatever you have passed to the generic class when you instantiated it.
class Zoo<T> {
static void putAnimal(T animal) {
// do stuff
}
}
Zoo<Ape> apeZoo = new Zoo<Ape>(); // you can now put apes (and chimps) here
Zoo<Reptile> monkeyZoo = new Zoo<Reptile>(); // this zoo takes reptiles
apeZoo.putAnimal(new Chimp());
monkeyZoo.putAnimal(new Tortoise());
For the first paragraph, this is just how generics work for classes. For instance, for list, you can create a list of a generic type, such as integer, e.g.:
ArrayList<Integer> list = new ArrayList<Integer>();
(in real code you'd use List<Integer> of course)
Now ArrayList will be defined as:
public class Arraylist<T> { // implements....
// ...
public T get(int index) {
// ...
}
}
Which is what makes it possible to use the get method on list and get an Integer (because we made a class of type ArrayList<Integer> so T = Integer). Otherwise the compiler would have no idea what types of objects the list was storing and you'd have to get the method to return an Object, which is how it used to be.
What the second paragraph means is that you can add type parameters to methods just as you can to classes. e.g.:
public <T> void noOp(T element) {
// code here
}
This would allow you, for instance, to create a static utility method that returns something of type T. To return the first element of a List of T's:
public static <T> T getFirst (List<T> list) {
return list.get(0);
}
And you could use this method in a strongly typed fashion. Suggestions for better examples welcome. :-)
edit: I just realised I once wrote something that uses this functionality. I was using the JPA API and getting really annoyed at all the times you have to return something (a list, or a single item) from a query, and running into unchecked type warnings because there's no way to infer the type here. If you're like me and trying to avoid warnings in your code, you'd have to suppress the warnings every single time. So I wrote this method to suppress the warnings for me:
#SuppressWarnings("unchecked")
public static <T> List<T> returnResultList(Query query) {
return (List<T>)query.getResultList();
}
Which through the magic of type inference works on:
List<Integer> list = returnResultList(query);