⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chapter17.html

📁 java 是一个很好的网络开发环境。由于它是通过解释的方法
💻 HTML
📖 第 1 页 / 共 5 页
字号:
          <font color=#0000ff>if</font>(in.sval.equals(<font color=#004488>"import"</font>) ||
             in.sval.equals(<font color=#004488>"package"</font>))
            discardLine();
          <font color=#0000ff>else</font> <font color=#009900>// It's an identifier or keyword</font>
            identMap.add(fname, in.sval);
        }
      }
    } <font color=#0000ff>catch</font>(IOException e) {
      e.printStackTrace();
    }
  }
  <font color=#0000ff>void</font> discardLine() {
    <font color=#0000ff>try</font> {
      <font color=#0000ff>while</font>(in.nextToken() != 
            StreamTokenizer.TT_EOF
            &amp;&amp; in.ttype != 
            StreamTokenizer.TT_EOL)
        ; <font color=#009900>// Throw away tokens to end of line</font>
    } <font color=#0000ff>catch</font>(IOException e) {
      e.printStackTrace();
    }
  }
  <font color=#009900>// StreamTokenizer's comment removal seemed</font>
  <font color=#009900>// to be broken. This extracts them:</font>
  <font color=#0000ff>void</font> eatComments() {
    <font color=#0000ff>try</font> {
      <font color=#0000ff>if</font>(in.nextToken() != 
         StreamTokenizer.TT_EOF) {
        <font color=#0000ff>if</font>(in.ttype == '/')
          discardLine();
        <font color=#0000ff>else</font> <font color=#0000ff>if</font>(in.ttype != '*')
          in.pushBack();
        <font color=#0000ff>else</font> 
          <font color=#0000ff>while</font>(<font color=#0000ff>true</font>) {
            <font color=#0000ff>if</font>(in.nextToken() == 
              StreamTokenizer.TT_EOF)
              <font color=#0000ff>break</font>;
            <font color=#0000ff>if</font>(in.ttype == '*')
              <font color=#0000ff>if</font>(in.nextToken() != 
                StreamTokenizer.TT_EOF
                &amp;&amp; in.ttype == '/')
                <font color=#0000ff>break</font>;
          }
      }
    } <font color=#0000ff>catch</font>(IOException e) {
      e.printStackTrace();
    }
  }
  <font color=#0000ff>public</font> String[] classNames() {
    String[] result = <font color=#0000ff>new</font> String[classes.size()];
    Enumeration e = classes.keys();
    <font color=#0000ff>int</font> i = 0;
    <font color=#0000ff>while</font>(e.hasMoreElements())
      result[i++] = (String)e.nextElement();
    <font color=#0000ff>return</font> result;
  }
  <font color=#0000ff>public</font> <font color=#0000ff>void</font> checkClassNames() {
    Enumeration files = classMap.keys();
    <font color=#0000ff>while</font>(files.hasMoreElements()) {
      String file = (String)files.nextElement();
      Vector cls = classMap.getVector(file);
      <font color=#0000ff>for</font>(<font color=#0000ff>int</font> i = 0; i &lt; cls.size(); i++) {
        String className = 
          (String)cls.elementAt(i);
        <font color=#0000ff>if</font>(Character.isLowerCase(
             className.charAt(0)))
          System.out.println(
            <font color=#004488>"class capitalization error, file: "</font>
            + file + <font color=#004488>", class: "</font> 
            + className);
      }
    }
  }
  <font color=#0000ff>public</font> <font color=#0000ff>void</font> checkIdentNames() {
    Enumeration files = identMap.keys();
    Vector reportSet = <font color=#0000ff>new</font> Vector();
    <font color=#0000ff>while</font>(files.hasMoreElements()) {
      String file = (String)files.nextElement();
      Vector ids = identMap.getVector(file);
      <font color=#0000ff>for</font>(<font color=#0000ff>int</font> i = 0; i &lt; ids.size(); i++) {
        String id = 
          (String)ids.elementAt(i);
        <font color=#0000ff>if</font>(!classes.contains(id)) {
          <font color=#009900>// Ignore identifiers of length 3 or</font>
          <font color=#009900>// longer that are all uppercase</font>
          <font color=#009900>// (probably static final values):</font>
          <font color=#0000ff>if</font>(id.length() &gt;= 3 &amp;&amp;
             id.equals(
               id.toUpperCase()))
            <font color=#0000ff>continue</font>;
          <font color=#009900>// Check to see if first char is upper:</font>
          <font color=#0000ff>if</font>(Character.isUpperCase(id.charAt(0))){
            <font color=#0000ff>if</font>(reportSet.indexOf(file + id)
                == -1){ <font color=#009900>// Not reported yet</font>
              reportSet.addElement(file + id);
              System.out.println(
                <font color=#004488>"Ident capitalization error in:"</font>
                + file + <font color=#004488>", ident: "</font> + id);
            }
          }
        }
      }
    }
  }
  <font color=#0000ff>static</font> <font color=#0000ff>final</font> String usage =
    <font color=#004488>"Usage: \n"</font> + 
    <font color=#004488>"ClassScanner classnames -a\n"</font> +
    <font color=#004488>"\tAdds all the class names in this \n"</font> +
    <font color=#004488>"\tdirectory to the repository file \n"</font> +
    <font color=#004488>"\tcalled 'classnames'\n"</font> +
    <font color=#004488>"ClassScanner classnames\n"</font> +
    <font color=#004488>"\tChecks all the java files in this \n"</font> +
    <font color=#004488>"\tdirectory for capitalization errors, \n"</font> +
    <font color=#004488>"\tusing the repository file 'classnames'"</font>;
  <font color=#0000ff>private</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> usage() {
    System.err.println(usage);
    System.exit(1);
  }
  <font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
    <font color=#0000ff>if</font>(args.length &lt; 1 || args.length &gt; 2)
      usage();
    ClassScanner c = <font color=#0000ff>new</font> ClassScanner();
    File old = <font color=#0000ff>new</font> File(args[0]);
    <font color=#0000ff>if</font>(old.exists()) {
      <font color=#0000ff>try</font> {
        <font color=#009900>// Try to open an existing </font>
        <font color=#009900>// properties file:</font>
        InputStream oldlist =
          <font color=#0000ff>new</font> BufferedInputStream(
            <font color=#0000ff>new</font> FileInputStream(old));
        c.classes.load(oldlist);
        oldlist.close();
      } <font color=#0000ff>catch</font>(IOException e) {
        System.err.println(<font color=#004488>"Could not open "</font>
          + old + <font color=#004488>" for reading"</font>);
        System.exit(1);
      }
    }
    <font color=#0000ff>if</font>(args.length == 1) {
      c.checkClassNames();
      c.checkIdentNames();
    }
    <font color=#009900>// Write the class names to a repository:</font>
    <font color=#0000ff>if</font>(args.length == 2) {
      <font color=#0000ff>if</font>(!args[1].equals(<font color=#004488>"-a"</font>))
        usage();
      <font color=#0000ff>try</font> {
        BufferedOutputStream out =
          <font color=#0000ff>new</font> BufferedOutputStream(
            <font color=#0000ff>new</font> FileOutputStream(args[0]));
        c.classes.save(out,
          <font color=#004488>"Classes found by ClassScanner.java"</font>);
        out.close();
      } <font color=#0000ff>catch</font>(IOException e) {
        System.err.println(
          <font color=#004488>"Could not write "</font> + args[0]);
        System.exit(1);
      }
    }
  }
}

<font color=#0000ff>class</font> JavaFilter <font color=#0000ff>implements</font> FilenameFilter {
  <font color=#0000ff>public</font> <font color=#0000ff>boolean</font> accept(File dir, String name) {
    <font color=#009900>// Strip path information:</font>
    String f = <font color=#0000ff>new</font> File(name).getName();
    <font color=#0000ff>return</font> f.trim().endsWith(<font color=#004488>".java"</font>);
  }
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The class <B>MultiStringMap</B> is
a tool that allows you to map a group of strings onto each key entry. As in the
previous example, it uses a
<A NAME="Index3036"></A><A NAME="Index3037"></A><B>Hashtable</B> (this time with
inheritance) with the key as the single string that&#8217;s mapped onto the
<B>Vector</B> value. The <B>add(&#160;)</B> method simply checks to see if
there&#8217;s a key already in the <B>Hashtable</B>, and if not it puts one
there. The <B>getVector(&#160;)</B> method produces a <B>Vector</B> for a
particular key, and <B>printValues(&#160;)</B>, which is primarily useful for
debugging, prints out all the values <B>Vector</B> by
<B>Vector</B>.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">To keep life simple, the class
names from the standard Java libraries are all put into a
<A NAME="Index3038"></A><B>Properties</B> object (from the standard Java
library). Remember that a <B>Properties</B> object is a <B>Hashtable</B> that
holds only<B> String</B> objects for both the key and value entries. However, it
can be saved to disk and restored from disk in one method call, so it&#8217;s
ideal for the repository of names. Actually, we need only a list of names, and a
<B>Hashtable</B> can&#8217;t accept <B>null</B> for either its key or its value
entry. So the same object will be used for both the key and the
value.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">For the classes and identifiers
that are discovered for the files in a particular directory, two
<B>MultiStringMap</B>s are used: <B>classMap </B>and <B>identMap</B>. Also, when
the program starts up it loads the standard class name repository into the
<B>Properties </B>object called <B>classes</B>, and when a new class name is
found in the local directory that is also added to <B>classes </B>as well as to
<B>classMap</B>. This way, <B>classMap</B> can be used to step through all the
classes in the local directory, and <B>classes</B> can be used to see if the
current token is a class name (which indicates a definition of an object or
method is beginning, so grab the next tokens &#8211; until a semicolon &#8211;
and put them into <B>identMap</B>).</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The default constructor for
<B>ClassScanner</B> creates a list of file names (using the <B>JavaFilter</B>
implementation of
<A NAME="Index3039"></A><A NAME="Index3040"></A><B>FilenameFilter</B>, as
described in Chapter 10). Then it calls <B>scanListing(&#160;)</B> for each file
name.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Inside <B>scanListing(&#160;)</B>
the source code file is opened and turned into a
<A NAME="Index3041"></A><A NAME="Index3042"></A><B>StreamTokenizer</B>. In the
documentation, passing <B>true </B>to <B>slashStarComments(&#160;)</B> and
<B>slashSlashComments(&#160;)</B> is supposed to strip those comments out, but
this seems to be a bit flawed (it doesn&#8217;t quite work in Java
1.0<A NAME="Index3043"></A>). Instead, those lines are commented out and the
comments are extracted by another method. To do this, the &#8216;<B>/</B>&#8217;
must be captured as an ordinary character rather than letting the
<B>StreamTokenizer</B> absorb it as part of a comment, and the
<B>ordinaryChar(&#160;)</B> method tells the <B>StreamTokenizer </B>to<B> </B>do
this. This is also true for dots (&#8216;<B>.</B>&#8217;), since we want to have
the method calls pulled apart into individual identifiers. However, the
underscore, which is ordinarily treated by <B>StreamTokenizer</B> as an
individual character, should be left as part of identifiers since it appears in
such <B>static</B> <B>final</B> values as <B>TT_EOF</B> etc., used in this very
program. The <B>wordChars(&#160;) </B>method takes a range of characters you
want to add to those that are left inside a token that is being parsed as a
word. Finally, when parsing for one-line comments or discarding a line we need
to know whe

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -