ssh update
. The name officially listed for your account is
under the "Change your Cecos" entry.
From the point of view of a program, these streams look like ordinary output files. Various programming languages provide different notations and library calls to refer to them. In Java programs, the standard output appears as the variable System.out and the standard error as System.err. Anything written to these (by, say, the printf method) comes out on the respective stream.
By default, both streams go to the terminal (or "console"). Unix shells provide various ways of directing them instead into separate files. Unfortunately, the various shells are inconsistent in how to do this. To run a command FOO (e.g., java solve test1.in), and send the output and error to various destinations:
Desired effect | csh-like shell | bash-like shell |
---|---|---|
Std. output -> blah Std. error -> terminal |
FOO > blah | FOO > blah |
Std. output -> blah Std. error -> blah |
FOO >& blah | FOO > blah 2>&1 |
Std. output -> blah1 Std. error -> blah2 |
(FOO > blah1) >& blah2 | FOO > blah1 2> blah2 |
You can also redirect the output of FOO to be the input of another command, BAR:
Desired effect | csh-like shell | bash-like shell |
---|---|---|
Std. output -> BAR Std. error -> terminal |
FOO | BAR | FOO | BAR |
Std. output -> BAR Std. error -> BAR |
FOO |& BAR | FOO 2>&1 | BAR |
Std. output -> BAR1 Std. error -> BAR2 |
(FOO | BAR1) |& BAR2 | (FOO | BAR1) 2&>1 | BAR2 |
We use all this in the autograder to separate or combine the output and error streams, as needed.
java foo < SOMEFILEruns foo but takes the standard input from SOMEFILE (a file name) rather than the keyboard. This works for any command, not just 'java'.
SOMECOMMAND | java fooruns SOMECOMMAND (any command) and java foo, taking the standard output from SOMECOMMAND and using it as the standard input for java foo.
System.setIn (SOMEINPUTSTREAM)where SOMEINPUTSTREAM can be any Java expression that yields an InputStream, such as
new FileInputStream (SOMEFILENAME)or
new StringBufferInputStream (SOMESTRING)
Eclipse provides a "Java build path" window under Project->Properties. The Libraries tab on that window will give you an "Add External Jar" selection. In plain UNIX, you add the Jar file to the CLASSPATH environment variable, which is a list of files separated by colons.
Static nested classes are just plain classes, like non-nested ones. The only thing that distinguishes them is where their names can be mentioned, and how they are referred to (class Nested inside class Enclosing is called Enclosing.Nested).
Non-static (inner) nested classes are plain classes with one extra implicit field. For inner class Inner in enclosing class Enclosing, if E is an Enclosing, then new E.Inner (...) is a pointer to a new object of type Enclosing.Inner that has a private instance variable field called Enclosing.this, whose value is E. So, given
class Enclosing { String myName; Enclosing (String name) { myName = name; } public String toString () { return "Enclosing named " + myName; } Inner makeInner (String id) { return this.new Inner (id); // OR return new Inner (id) for short ('this.' implied) } class Inner { String innerName; Inner (String name) { innerName = name; } public String toString () { return "Inner named " + innerName + " connected to " + Enclosing.this; } } }we could write (in some method somewhere):
Enclosing e = new Enclosing ("Tom"); Enclosing.Inner i1 = e.makeInner ("Dick"); Enclosing.Inner i2 = e.new Inner ("Harry"); System.out.printf ("e = %s%ni1 = %s%ni2 = %s%n", e, i1, i2);and see printed
Enclosing named Tom Inner named Dick connected to Enclosing named Tom Inner named Harry connected to Enclosing named Tom
makeInner ("Jack")
the Java compiler would assume that you must have meant to write
Enclosing.this.makeInner ("Jack");
For qualified names, SOMETHING.x, we look for 'x' only within SOMETHING (which may be a package, class, or instance). For this purpose, we count inherited declarations as being in the class or interface that inherits them.
So far, these rules will in general pick out several possible declarations,
as in the following
class A { // a A A; // 1 b A A (A A) { return A; } // 2 c 3 d 4 A () { } // e } class B extends A { // f void A () { // g A A = A (new A ().A); // 7 h 8 9 10 } }
Here, I have marked each use of A with a numeral and each definition with a lower-case letter.
Initially, use #8 might refer to the declarations a (same file); b, c,
or e (inherited by class B), g, or h. First, however, we apply
Or consider #9. By context, it must refer to a class, which means declaration a, and a constructor within that class, which can only be e.
Since the thing to the left of the dot preceding #10 is an A, #10 must refer to either declaration b, c, or e. Since it is not a method call or constructor invocation, it must refer to b.
Sometimes, these considerations of context or argument lists are not sufficient, as in use #4, which might refer to either b or d. In this case, we defer to the INNERMOST declarative region, which in this case is the method containing use #4. That is #4 refers to d.
Staticness has nothing whatever to do with any of this analysis. Neither
does access level (public, private, etc.), with the exception that
private declarations are not visible outside their package, which may
cut down on the set of possible candidate declarations. (Other access
levels, such as default (package private)
Therefore, runtime selection of instance methods by dynamic type is a separate mechanism, and does not participate in determining which declaration the compiler applies to some use. It is only when the program is run that the system actually selects which method to call. It will always be one that has the same signature as the one the compiler selected.
x = "Hello, "; "Hello, world" != x + "world"This is semantically consistent, but admittedly confusing. Use the .equals method instead:
"Hello, world".equals (x + "world")
Note: foo.java uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details.in particular mean that you have a construct that cannot be checked until execution time, whereas it is usually checkable at compilation time if the program is written correctly. If you do this:
ArrayList foo = ...instead of
ArrayListfor example, you'll get a warning. You should correct all of these (our pretests often require it, for example). In almost all cases, you can correct them without a problem. For this project, you are likely to find a couple of instances in which you run into a limitation of Java and will have to use thefoo =
@SuppressWarnings ("unchecked")annotation before a method or constructor. In my project #2, I had two on small methods. If you have any more than that, or if you have to attach it to an entire class, you are probably doing something wrong.
The messages ask you to run javac like this:
javac -Xlint:unchecked foo.javaas our Makefiles are set up to do. This will give you more details. In Eclipse, you should eliminate all the little yellow warning flags.
Characters in a stream or reader, on the other hand, are read
verbatim, without escape sequences. So backslash is just backslash, and
two backslashes are just two backslashes. So, your example is really
equivalent to the Java test "(hello)".matches ("\\\\(hello\\\\)")
,
which is indeed false. The argument to .matches
here, coming
from a String literal, contains the characters backslash, backslash,
left parenthesis, etc.—each pair of backslashes in the literal encodes a
single backslash in the resulting String.
To make the confusion worse, backslashes have special significance in Patterns, too. So the Pattern consisting of two backslashes could be input from a file as two backslashes or else written as a String literal with four backslashes, and is interpreted by the Pattern class as matching ONE backslash!
svn statuswill show you what your Subversion client program (
svn
) thinks
is the status of each of your files in that directory. E.g.,
% svn status A Progs.java ? Progs.class ? MyUtils.java M HW1Test.javaThis tells you that you have told
svn to place Progs.java under
version control (keep copies of it), but have not yet told the repository
about this; that there are files named Progs.class and MyUtils.java that are
in the directory but not under version control; and that the file
HW1Test.java is in the repository, but the working copy here in the
~/svnwork/hw1 directory has been modified since the last commit operation.
Presumably, you'll want to submit MyUtils.java, so tell svn
with
svn add MyUtils.java
You don't care about keeping copies of Progs.class (and we've set up the
repository to refuse them if you do), so now you're ready to send a copy
of the indicated files to the repository. The command is
svn commit -m "Descriptive log message"
(again, we're assuming you are in ~/svnwork/hw1; the commit would also work
from ~/svnwork, but would then commit any other directories with outstanding
changes as well).
At this point, you will generally want to do
svn update
as well, which says "Just check the repository to make sure we are up to
date with any changes that somebody else is making." There isn't anyone else
in this course, but Subversion doesn't know that.
cd ~/svnwork svn update svn copy -m "Submit HW#1." \ hw1 svn+ssh://cs61b-ta@HOST/LOGIN/tags/hw1-N(Replace HOST with the name of the SVN server you are currently using, such as pulsar.cs.berkeley.edu. Replace LOGIN with your account name. Replace N with a sequence number (1, 2, etc.), so as to keep multiple submissions of hw1 distinct.) The trailing backslash on the first line of
svn copy
is the line continuation character
in Unix.
Another possibility (although it does not check that you have committed your trunk) is
svn copy -m "Submit HW#1." \ svn+ssh://cs61b-ta@HOST/LOGIN/trunk/hw1 \ svn+ssh://cs61b-ta@HOST/LOGIN/tags/hw1-Nor, using Unix shell expansions
svn copy -m "Submit HW#1." \ svn+ssh://cs61b-ta@HOST/LOGIN/{trunk/hw1,tags/hw1-N}
svn
will go to that server, and if that server is down, the
operation will fail. You can tell svn
to use a different
server with a command like the following (here, we'll change from the
old server quasar to the new server pulsar):
cd ~/svnwork svn switch --relocate svn+ssh://cs61b-ta@quasar.cs.berkeley.edu \ svn+ssh://cs61b-ta@pulsar.cs.berkeley.eduor, using Unix shell expansions:
cd ~/svnwork svn switch --relocate svn+ssh://cs61b-ta@{quasar,pulsar}.cs.berkeley.edu(the trailing backslash in the first variation is the shell line continuation character).
Repeat this command sequence in your ~/staff directory as well, since you'll
want to use a consistent server for all your work (otherwise, svn
will think it is referencing two different repositories).
cd ~/svnwork/hw1 svn commit -m "Fill in Progs.java"are giving you grief, for example, type the command
svn info ~/svnwork/hw1and look to see if the URL line says something like
URL: svn+ssh://cs61b-ta@pulsar.cs.berkeley.edu/staff/hw1This tell us that Subversion thinks that the working directory ~/svnwork/hw1 is associated with staff/hw1 in the Subversion repository. What this tells me is that you got this directory originally with
cd ~/svnwork svn checkout svn+ssh://cs61b-ta@.../staff/hw1I've also seen this:
cd ~/svnwork mv ~/staff/hw1 hw1and this:
cd ~/svnwork cp -r ~/staff/hw1 hw1where you've previously checked out the staff repository into ~/staff. Naturally, we can't allow you to modify the public files, so we've set up Subversion to deny access when you attempt to write to these files.
Instead, to copy files from our staff directory to your trunk, use
# Do the next two commands if necessary cd ~/staff svn update cd ~/svnwork svn copy ../staff/hw1 hw1 svn commit -m "Initial version of hw1"If you do an 'svn info hw1' at this point, you'll see that the URL is something like URL: svn+ssh://cs61b-ta@pulsar.cs.berkeley.edu/cs61b-yu/trunk/hw1 That is, it's a whole new repository directory under your control.
svn commit
and eventually got the message
svn: Can't copy /home/cc/.../svn/submit/lab3/trunk/BankAccountTest.java' to /home/cc/.../svn/submit/lab3/trunk/.svn/.../BankAccountTest.java....': No such file or directoryand
svn status
shows
... A submit/lab3/trunk ! submit/lab3/trunk/IntSequence.java ...Those '!'s mean "he used to have this file under version control and now it has vanished mysteriously." Perhaps you mv'ed them out of
submit/lab3/trunk
to submit/lab3
and then svn added them to submit/lab3
. Or perhaps you
simply rm'ed them. Either one will do it: the files in your working directory
get out of sync with what svn assumes is supposed to be there.
When dealing with files A and B under version control, use
svn move A Binstead of
mv A Band use
svn remove Ainstead of
rm AAnd, of course, you'll need to commit those changes at some point.
cd ~/svnwork/proj2 svn merge svn+ssh://cs61b-ta@HOST/tags/proj2-N \ svn+ssh://cs61b-ta@HOST/staff/proj2[Or, a better use of Unix for the second command:
svn merge svn+ssh://cs61b-ta@HOST/{tags/proj2-N,staff/proj2}]
svn resolved FILENAMEto tell Subversion that this file is no longer a problem (it won't let you commit otherwise).