Macon Pegram

Greenhorn
+ Follow
since Mar 01, 2002
Merit badge: grant badges
For More
Cows and Likes
Cows
Total received
In last 30 days
0
Forums and Threads

Recent posts by Macon Pegram

The system internally keeps a count of the number of references that are currently active for a given object. When a new reference is added, that reference counter is incremented by 1. Conversely when a reference is removed it's decremented. Once that internal reference count reaches 0, an object is eligible for garbage collection.
Corey's flash animation is a great tool, and his suggestion of "drawing lines" for each reference will help you diagram out what's going on.
A couple of more bits of information related to Garbage Collection (some on the test, some just nice to know).
- Garbage Collection algorithms are largely left up to the VM implementer. After an object is marked available for collection there is no definite way to tell when it is actually going to be collected.
- According to the spec, calling System.gc() only SUGGESTS that system expend effort performing garbage collection. It does NOT guarantee it. Again, this is an implementation detail left up to the VM creator.
- Garbage collection runs as a lower priority thread than your applications do. If you have a very busy system, the GC may not run for a long time. I've actually seen this on some heavily loaded servlet based systems where data piles up for hours before GC finally gets a chance to kick in.
- The garbage collector will not collect an object until it's finalization is completed. It's better to clean early than rely on finalize for cleanup. Otherwise it may take more than one pass of the GC thread to reclaim the memory that was allocated.
For more insights into GC and finalization, check out the discussion in the JLS
Macon
public static void main(String [] args) should be thought of as a "contractual agreement" between the programmer and the developers of the Java langauge.
They agreed to start execution of your program at a well defined point in your code, and you need only provide the REQUIRED interface. So by not providing a main method that meets the "contract", you are "violating" your end of the agreement when you ask the Java language to RUN your code.
It's like telling someone to pull an object out of a glass box, but not providing any entry point to that box.
Macon
You beat me to it Vallentin! I was just getting ready to post that exact same comment!
Macon
Interface methods merely describe a contract that an implementing class must fufill. They do not describe in any way the implementation details.
native and synchronized refer to implementation details that are not only not known, but also not relevant when specifying an interface.
It's all about the references...
given the code:

We've already established that "abc" is stored on the heap only once and that variable a refers to the heap memory location of "abc" and that variable b refers to the same heap memory location of "abc" (as a quickie review.. remember variables that are not primative REFER to objects.. they are not the objects themselves).
So with all that in mind == will compare the value of the references, not the actual value contained within those references.
We use the equals() method to do a character by character comparison of two strings. To think of it differently. Look at the following:

In the code fragment above if statement // 3 will print out "b == c" because in line //1 we copy the REFERENCE of b into c.
When if statement // 4 runs however "b != d" will be printed despite the fact that the value refered to by each of the variables equivalent. The REFERENCE to those two values is different. b refers to an instance of Integer on the heap that contains the value 5, while d refers to a DIFFERENT instance of Integer on the heap that also happens to contain the value 5. To make this work correctly we should change the if statement in line 4 as follows:

This would work because it's comparing actual values as opposed to references, and as a result would output "b == d".
It is a typo... B should read:
throw new MyException()
not "throws". "throws" indicates possible exceptions a method may throw (and is used as part of the method definition. "throw" is used to explicitly throw an exception.
I would have agreed with you that only E was correct given the options.
That is because the null parameter is non-deterministic. null can be used in assignments to any type of object. Your overloaded methods each take one object parameter. It is impossible to determine if your intent is to pass the null to the method that takes the String or the StringBuffer. So your reference to the method is ambiguous.
If you had a method that took a primitive and another took an object however your code would compile (because only 1 signature is looking for an object, and null cannot be assigned to a primitive).
Try out this code:

This code will print "String Version" when run.
[ March 05, 2002: Message edited by: Macon Pegram ]
You probably don't want to use "FilterInputStream" directly as a class. It's more likely that you will want to use one of it's subclasses like "BufferedInputStream", "CheckedInputStream", or "DataInputScreen" (again, take a look at the API docs for more specifics). These all provide public constructors. You may also want to create your own filtered input stream in which case you would subclass FilterInputStream and provide your own public constructor.
In reference to your code specifically, if you want to make it compile and work, you will need to make a couple of changes:
1. Your signature for main should be public static void main(String []args) (you left out public scope and the static)
2. Try creating an instance of one of the subclasses of FilterInputStream.
Below is a modified example of your code that will compile and run:

One other note... The way your program runs right now.. if the file exists, it will say "file found", but if the file does not exist you will actually see the output:
file no
file found
This is because the finally block always runs (even if there's an exception).
One possible variation on your code that would probably accomplish what you set out to do would be as follows:


[ March 03, 2002: Message edited by: Macon Pegram ]
It is not possible to create an instance of an abstract object, but the signature you provided is perfectly legitimate.
Think "Polymorphism".
public void eatMeth() throws BadTasteException
This says that we will be throwing an exception that conforms to the contract specified by BadTasteException. In the method eatMeth() you may throw any sub-class of BadTasteException because as descendants of BadTasteException they fufill the contract specified by BadTasteException's definition. So you could throw BitterException and/or SourException within eatMeth(). This of course assumes that these subclasses are not abstract themselves.
If you think about this in the context of some exceptions you've probably dealt with in the past this probably makes even more sense. An excellent example would be when you deal with IO functions. typically you will set these up in a try/catch block where you "catch" an IOException object. IOException is actually the parent class for a number of exceptions like "FileNotFoundException". Yet when you setup your try catch you don't have to catch every type of IOException individually... You can simply catch the parent if that suits your needs.
Hope this helps!
[ March 02, 2002: Message edited by: Macon Pegram ]
While this is somewhat of a guess, I believe the correct answer is that your call to giveMeJ() happens PRIOR to the assignment statement in the line below it. Remember that when an int is first created, it is assigned the value of 0 until you explicitly assign it a different value.
The code in it's current state is fine. It's perfectly acceptable to assume that this code will run as a thread.
The only problem with the code (and the reason it does nothing) is that you must do more than simply create a thread.. you must start it. In order for the code to actually output "Working..." your start() method would have to look like this: