Jump to content

Aeternus

Senior Members
  • Posts

    349
  • Joined

  • Last visited

Everything posted by Aeternus

  1. I'm a little confused by what you mean.... do you want multiple broadband connections connected to the same pc to try and boost your overall connection speed? Or do you simply wish to connect multiple computers to the same internet connection (in which case, get a router or use some form of routing software (Windows has internet connection sharing)).
  2. With regard to question 6, http://www.agiledeveloper.com/articles/GenericsInJavaPartII.pdf will probably help explain it more easily. It explains the reasons that things like that can be done, and explains that if you show the warnings you will see that it does inform you of your error in doing this but it won't actually error because of the way it handles generics underneath.
  3. On my system, I get no answer, and no answer. If I correct the for loop to start at 0 (given that Java doesn't pass in the name of the script like in some other environments/langauges), I get "1234". I can do java Test "1234 567" 567 and change your print to println, I get - 1234 567 567 because the quotes have shown the shell/command line/jvm that that should be taken as one argument. The way in which arguments are passed to the script might be slightly different based on the shell/os but I'd imagine the JVM tries to ensure some degree of consistency. http://java.sun.com/docs/books/tutorial/essential/attributes/cmdLineArgs.html
  4. Perhaps this - http://butunclebob.com/ArticleS.UncleBob.BoundedWildcards - will be of use to you. The point is in the case of super, you will be able to add anything to that list that is Integer or derived from Integer (which may sound confusing given the definition). The point is, it doesn't mean that this list can store anything that is a super of Integer, it means this variable can store a list of anything that is a super of Integer, there is a difference. This works because for instance - List<Object> l = new ArrayList<Object>(); l.add(new Integer()); would work because an Integer can be stored as an Object because it is derived from it. For this same reason, we know that anything that is a super of a particular type can store an object of that type, so in compiler checking the compiler will make sure that anything being passed into the object is an Integer or derived from an Integer, because those are the only thing is can guarantee can be passed to it For instance, say we have 3 classes such that, A, B extends A, C extends B and then we have - List<? super C> l = new ArrayList<B>; l.add(new A()); doesn't work, simply because you can only add C or lower to it as it can only guarantee that those types can be added. Extends has the opposite problem, by accepting any list that can contain objects of a type that extends the given type, you don't really know at all what type of objects you can store in it because the class could be anywhere down the class hierarchy and anything above that wouldn't be storable in the list. Sorry if this seems a little unclear. The blog/article (not sure if I've already posted it) might help clear things up.
  5. http://butunclebob.com/ArticleS.UncleBob.BoundedWildcards That's quite a nice entry on how you can use wildcards although it still doesn't go indepth into some bits that would be nice.
  6. If you read what I said, if you actually put that in a try-catch block and run it, you will see that it has been overriden. As I said I think you get that compiler error because it does checks at compiler time based on the method headers of the methods of the class/type of the variable, not those of the class being instantiated to create the variable.
  7. Eh? If you actually put it in a try - catch block you will see that b.meth overrides a.meth in both cases. The only reason it requires that is because the method signature in "a" specifies that the method can throw an exception and so it must be caught. I have no idea why it does it like this but as you can see the method is still overridden. I think it is because at compiler time, it checks these sort of things against the type/class of the variable (ie a not b), for simplicity, as you might do funky things with class loading and so on that might mean that the actual instantiated class might not be known. I know it IS known in this case but they might not bother to actually check this, or conversely there might be some other reason that it does this. Either way, both of those methods are being overriden in the same way.
  8. Umm... I think you are wrong. It compiles fine for me. The reason you might be getting an error is because you are missing the final ). import java.util.*; public class Test{ public static void main(String[] ag){ List<Object> l = new ArrayList<Object>(); l.add(new String("cheese")); l.add(new Object()); l.add(new Integer(5)); Iterator i = l.iterator(); while (i.hasNext()) { System.out.println(i.next()); } } } compiles fine and when run produces the output - cheese java.lang.Object@2e7263 5 What compiler error are you getting?
  9. The code sample I provided was meant to illustrate how to avoid getting an IllegalMonitorStateException. The code you originally provided generates an IllegalMonitorStateException when you chuck it in a class and try to run it (or at least it did with me. For instance I put your original code segment into a class and compiled like so - public class Thread2 { public void wfs() throws InterruptedException { Object o = new Object(); synchronized (Thread.currentThread()){ o.wait(); o.notify();; } } public static void main(String args[]) throws InterruptedException { Thread2 t = new Thread2(); t.wfs(); } } and when run (on 1.4 and 1.5) this gives - Exception in thread "main" java.lang.IllegalMonitorStateException: current thread not owner at java.lang.Object.wait(Native Method) at java.lang.Object.wait(Object.java:474) at Thread2.wfs(Thread2.java:9) at Thread2.main(Thread2.java:18) I altered the code to change - synchronized (Thread.currentThread()){ to synchronized (o) { which when run works ok, but as expected will simply sit there indefinitely waiting for a notify() call that never comes. Basically my code segment was simply to illustrate how one would do things to avoid that exception. Sorry if this was a little unclear.
  10. I think (5) is a simple misunderstanding of what is going on. You pass it an object, it uses the hash from object.hashCode() (which you overrided) to determine a hash key to use to put it in the HashMap uses by HashSet to store things. The only time it checks for duplication is when you try to add something new. The way it seems to do this is simply by checking for collisions in the hash map. The idea being that if they have the same key they will try to add to the same position in the Hashtable. When this collision is detected (ie you look at the position in the hashtable, it is already occupied, there has been a collision), it will then check to make sure this hasn't simply been a random collision (ie because of the hash function, 2 different objects might collide anyway) by using equals to test if they are equal, if they are equal then the add() will simply fail, if they aren't then some form of collision resolution will be used and the new entry will be placed somewhere sensible. The problem here is that if the hash key/code isn't the same for the new object being put in, then it can't be the same as another object because they probably won't match to the same position in the HashMap / HashTable and so won't have a chance to be compared with equal(). Sorry if this sounds a little confusing, perhaps the best way to explain this is to just go through each instance of the set.size() calls and explain what is happening at each - // The First one set.add(k1);set.add(k1); set.add(k2);set.add(k2); System.out.print(set.size() +":"); k1 returns the hashcode k1, and k1.equals(k1) so the second set.add(k1) will collide with the entry in the HashMap for the first and will be equal to it and so the second add will fail. The same is true with the second set.add(k2). Therefore we have 2 elements in the HashSet, so set.size() returns 2. // Second k2.i=1; System.out.print(set.size() +":"); Here, the statement, k2.i = 1; has made k1 equal to k2, however, the HashSet won't do anything about it as it only checks for duplication when you add the objects, it doesn't try to maintain this uniqueness whenever you change other things (how could it? none of it's methods are being run right now?). Therefore, the HashSet still has 2 elements and they are still at different positions (k2 doesn't move simply because it's hashcode has changed, that code was used to place it in the first place, but changing that code doesn't change the fact that it was placed in the table at the original hash code value). Therefore, as there are still 2 elements and no checks and so on have been done, set.size() will return 2. set.remove(k1); System.out.print(set.size() +":"); set.remove(k1), uses the k1.hashCode() to find the position of k1 in the hashtable, k1 equals() the element at that position, so it removes that element from the table. It doesn't go off searching for other elements that might equal k1 because it assumes that if they did, they would have been discarded when they were add(). Now there is only 1 element in the HashSet left which wasn't removed because duplication avoidance is handled by add(). Therefore, as there is 1 element, set.size() returns 1. // Four set.remove(k2); System.out.print(set.size()); This is the funky bit, as k2.i has now changed to 1 (it was originally 2), k2.hashCode() will return 2, and HashSet will use that to look for it, but there is nothing at the position because that was the position taken by k1, k2 was originally placed into whatever place is specified by "2" not "1". Therefore as it can't find k2, it simply fails. k2 has not been removed, it is still at "2", it hasn't moved, it is simply that the hashCode() has changed and so HashSet tries to look for it in a different place. Since there is still 1 element in the HashSet (k2), set.size() returns 1. Therefore it prints 2:2:1:1 You can further reinforce alot of this by either making hashCode() return a constant or by making it return a different value every time (one way of doing this is to have a static field that is incremented every time hashCode() is called) and then using the iterator() of HashSet to see what is going on inside. Sorry if some of this seems a little rushed or lacks some explanation, I have to go off up town now so I'll be back later to try and clear things up.
  11. The reason you are getting an IOException in (4) is because you are calling g.createNewFile(), but you passed f as the parent to g, which implies that f is a directory, but you are creating f as a new file not a new directory, and so when you tried to create g, it throws an IOException as it can't treat a file (f) as a directory and so it can't create g inside f. To get this to work you need to do - import java.io.*; public class Files { public static void main(String[] ag){ try{ File f = new File("f"); File g = new File(f, "g"); if(!f.exists()){ f.mkdir(); } if(!g.exists()){ g.createNewFile(); } } catch(IOException ioe) { ioe.printStackTrace(); //System.out.println(ioe); } } } You'll notice I used f.mkdir() to create f as a directory and not as a file. You'll also notice that I did ioe.printStackTrace() instead of just printing ioe, which can make it a little easier to track things down sometimes.
  12. With regard to (2), I'm a little confused by the question. It outputs "a:b"... what is the problem with that? The PriorityQueue will order things according to their natural order, so it will put "a" at the head, then "b", then "c". You are printing pq.poll(), which grabs the head, removes it from the queue and returns it. So in this case, it removes "a" and returns "a". Then you are peeking at the head of the priority queue which is now "b", therefore you have "a" + ":" + "b" which is "a:b" which is what it prints out :\ Am I misunderstanding you or something? Did it print "b:c" for you? Have I misunderstood something?
  13. I think the reason for (2) is that - List<? extends Object> paramName implies that that parameter can take any list that can hold any type of Object or of any type of subclass of Object. Say for instance you did - ... // Some Method public void doit(List<? extends Object> d) { d.add(new Object()); } ... List<String> list = new ArrayList<String>(); doit(list); ... Obviously I'm missing alot of code but I hope you get the idea. Now doit() takes in any List that can hold any subtype of Object or Object itself. So I've passed in my List that holds String's, it doesn't make sense for me to now add an Object to a list that holds String s as the base class that this list holds is String, not Object. Ie - List<String> x = new ArrayList<String>(); x.add(new Object()); won't work, and therefore, I think that is the same reason as why the code errors. This is all a bit silly with String as String is final anyway and so nothing can actually extend String but I'm guessing it isn't going as far as to see what actually IS being passed to the method but only what could be and should be legal? The reason it works with super is that if the list stores any class/type that is a super type of the class specified then an object of the class you specified can be stored in any of those lists because it is extended from that class. Ie - List<Object> x = new ArrayList<Object>(); x.add(new String()); works because you can do Object x = new String(); because String is a subclass of Object, and Object is super type of String. Not sure if this makes sense but that's how it seems things are working to me.
  14. Ok with regard to (1), I think this is because you are redeclaring "a" in Bar but are typecasting it to Foo, and therefore accessing the "a" that was declared in Foo, not that which has been declared an altered by the methods from Bar. This is rather hard to explain but if you simply take out "public int a;" from the Bar class, this should fix it. Another fix which might make things more clear is changing the Bar class to - public class Bar extends Foo{ public int a; public Bar(){super.a = 8;} public void add(){super.a+=5;} } This ensures that the a declared in the super class (Foo) is set to these values and not the new "a" declared in Bar.
  15. I still get errors about no return type for Bar.Foo() and even if I comment that out, printing foo simply gives me the object reference "Bar@10d448" (as you would expect as the toString method hasn't been overridden).
  16. [Referring to the first question] How are you getting that to compile? Firstly Foo.add(), Bar.add() and Bar.Foo() need return types (otherwise the compiler errors on (1.4 and 1.5)). Secondly, Foo and Bar are not compatible types :\ Am I missing something? Are you using a different compiler to me?
  17. As far as I can see, Runnable doesn't mean "Running", it means exactly what is says, "Runnable", ie able to be executed. I'm guessing you are reading - http://java.sun.com/docs/books/tutorial/essential/threads/lifecycle.html ? If you read further down to a section called "Making a Thread Not Runnable", you will see that Not Runnable simply means that the thread scheduler can't begin executing this thread as it is in a state in which executing it would be a mistake (ie it is sleep()ing for instance or wait()ing on something), not that the thread isn't executing. When you call yield(), the thread you call it on doesn't lose the ability to be executed (ie if you just had that one thread it would just continue running as normal afaik), it is simply moved to a later point in the schedulers queue so that other threads in the Runnable state can be executed. State's that are in the Not Runnable state won't be considered for execution time as they are "Not Runnable" for some reason or other.
  18. The only exception similar to what you are talking about that is actually thrown by Object.wait() (or notify() but that isn't really important as it won't reach that in this example) in this example is IllegalMonitorStateException which is thrown in this case when wait() is called on Object o, because whatever object the wfs method is a part of, hasn't grabbed the monitor/lock for Object o and so can't call wait() on it, hence it throws the IllegalMonitorStateException. The example currently synchronizes on the current thread (and hence gains a lock/monitor on the current thread object) but that isn't that same as having ownership of the monitor/lock of the Object o. To gain ownership of it's monitor and the ability to call wait() on it you have to do - public void wfs() { Object o = new Object(); synchronized (o) { o.wait(); o.notify();; } } That way you are synchronizing on o, gaining it's lock/monitor in the process and therefore you are allowed to call wait() on it and an IllegalMonitorStateException can't be thrown. I'm not sure whether an IllegalStateException can also be thrown somehow (and I can't see IllegalMonitorStateException extending to IllegalStateException) but I'm guessing maybe it was just a typo or something similar? I could be wrong on some of this, this is just how I see it.
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.