86. Java代码查错(4)
public class Something {
?? public int addOne(final int x) {
?????? return ++x;
?? }
}
此代码有错误吗?
答案: 错。int x被修饰成final,意味着x不能在addOne method中被修改。
87. Java代码查错(5)
public class Something {
?? public static void main(String[] args) {
?????? Other o = new Other();
?????? new Something().addOne(o);
?? }
?? public void addOne(final Other o) {
?????? o.i++;
?? }
}
class Other {
?? public int i;
}
此代码有错吗?
答案: 正确。在addOne method中,参数o被修饰成final。如果在addOne method里我们修改了o的reference
(比如: o = new Other();),那么如同上例这题也是错的。但这里修改的是o的member vairable
(成员变量),而o的reference并没有改变。
88. Java代码查错(6)
class Something {
??? int i;
??? public void doSomething() {
??????? System.out.println("i = " + i);
??? }
}
此代码有错误吗?
答案: 正确。输出的是"i = 0"。int i属於instant variable (实例变量,或叫成员变量)。instant variable有default value。int的default value是0。
89. Java代码查错(7)
class Something {
??? final int i;
??? public void doSomething() {
??????? System.out.println("i = " + i);
??? }
}
此代码有错误吗?
答案: 错。final int i是个final的instant variable (实例变量,或叫成员变量)。final的instant variable没有default value,必须在constructor (构造器)结束之前被赋予一个明确的值。可以修改为"final int i = 0;"。
90. Java代码查错(8)
public class Something {
???? public static void main(String[] args) {
??????? Something s = new Something();
??????? System.out.println("s.doSomething() returns " + doSomething());
??? }
??? public String doSomething() {
??????? return "Do something ...";
??? }
}
此代码有错误吗?
答案: 错。看上去在main里call doSomething没有什么问题,毕竟两个methods都在同一个class里。但仔细看,main是static的。static method不能直接call non-static methods。可改成"System.out.println("s.doSomething() returns " + s.doSomething());"。同理,static method不能访问non-static instant variable。
91. Java代码查错(9)
此处,Something类的文件名叫OtherThing.java
class Something {
??? private static void main(String[] something_to_do) {???????
??????? System.out.println("Do something ...");
??? }
}
此代码有错误吗?
答案: 正确。从来没有人说过Java的Class名字必须和其文件名相同。但public class的名字必须和文件名相同。
92. Java代码查错(10)
interface? A{
?? int x = 0;
}
class B{
?? int x =1;
}
class C extends B implements A {
?? public void pX(){
????? System.out.println(x);
?? }
?? public static void main(String[] args) {
????? new C().pX();
?? }
}
此代码有错误吗?
答案:错误。在编译时会发生错误(错误描述不同的JVM有不同的信息,意思就是未明确的x调用,两个x都匹配(就象在同时import java.util和java.sql两个包时直接声明Date一样)。对于父类的变量,可以用super.x来明确,而接口的属性默认隐含为 public static final.所以可以通过A.x来明确。
93. Java代码查错(11)
interface Playable {
??? void play();
}
interface Bounceable {
??? void play();
}
interface Rollable extends Playable, Bounceable {
??? Ball ball = new Ball("PingPang");
}
class Ball implements Rollable {
??? private String name;
??? public String getName() {
??????? return name;
??? }
??? public Ball(String name) {
??????? this.name = name;???????
??? }
?? public void play() {
??????? ball = new Ball("Football");
??????? System.out.println(ball.getName());
??? }
}
此代码有错误吗?
答案: 错。"interface Rollable extends Playable, Bounceable"没有问题。interface可继承多个interfaces,所以这里没错。问题出在interface Rollable里的"Ball ball = new Ball("PingPang");"。任何在interface里声明的interface variable (接口变量,也可称成员变量),默认为public static final。也就是说"Ball ball = new Ball("PingPang");"实际上是"public static final Ball ball = new Ball("PingPang");"。在Ball类的Play()方法中,"ball = new Ball("Football");"改变了ball的reference,而这里的ball来自Rollable interface,Rollable interface里的ball是public static final的,final的object是不能被改变reference的。因此编译器将在"ball = new Ball("Football");"这里显示有错。
答:
package cn.itcast;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
public class MainClass{
public static void main(String[] args) throws Exception{
FileManager a = new FileManager("a.txt",new char[]{'\n'});
FileManager b = new FileManager("b.txt",new char[]{'\n',' '});
FileWriter c = new FileWriter("c.txt");
String aWord = null;
String bWord = null;
while((aWord = a.nextWord()) !=null ){
c.write(aWord + "\n");
bWord = b.nextWord();
if(bWord != null)
c.write(bWord + "\n");
}
while((bWord = b.nextWord()) != null){
c.write(bWord + "\n");
}
c.close();
}
}
class FileManager{
String[] words = null;
int pos = 0;
public FileManager(String filename,char[] seperators) throws Exception{
File f = new File(filename);
FileReader reader = new FileReader(f);
char[] buf = new char[(int)f.length()];
int len = reader.read(buf);
String results = new String(buf,0,len);
String regex = null;
if(seperators.length >1 ){
regex = "" + seperators[0] + "|" + seperators[1];
}else{
regex = "" + seperators[0];
}
words = results.split(regex);
}
public String nextWord(){
if(pos == words.length)
return null;
return words[pos++];
}
}
(大家正在做上面这道题,网上迟到的朋友也请做做这道题,找工作必须能编写这些简单问题的代码!)
答:listFiles方法接受一个FileFilter对象,这个FileFilter对象就是过虑的策略对象,不同的人提供不同的FileFilter实现,即提供了不同的过滤策略。
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class Jad2Java {
public static void main(String[] args) throws Exception {
File srcDir = new File("java");
if(!(srcDir.exists() && srcDir.isDirectory()))
throw new Exception("目录不存在");
File[] files = srcDir.listFiles(
new FilenameFilter(){
public boolean accept(File dir, String name) {
return name.endsWith(".java");
}
}
);
System.out.println(files.length);
File destDir = new File("jad");
if(!destDir.exists()) destDir.mkdir();
for(File f :files){
FileInputStream ?fis = new FileInputStream(f);
String destFileName = f.getName().replaceAll("\\.java$", ".jad");
FileOutputStream fos = new FileOutputStream(new File(destDir,destFileName));
copy(fis,fos);
fis.close();
fos.close();
}
}
private static void copy(InputStream ips,OutputStream ops) throws Exception{
int len = 0;
byte[] buf = new byte[1024];
while((len = ips.read(buf)) != -1){
ops.write(buf,0,len);
}
}
}
由本题总结的思想及策略模式的解析:
1.
class jad2java{
1. 得到某个目录下的所有的java文件集合
1.1 得到目录 File srcDir = new File("d:\\java");
1.2 得到目录下的所有java文件:File[] files = srcDir.listFiles(new MyFileFilter());
1.3 只想得到.java的文件: class MyFileFilter implememyts FileFilter{
public boolean accept(File pathname){
return pathname.getName().endsWith(".java")
}
}
2.将每个文件复制到另外一个目录,并改扩展名
2.1 得到目标目录,如果目标目录不存在,则创建之
2.2 根据源文件名得到目标文件名,注意要用正则表达式,注意.的转义。
2.3 根据表示目录的File和目标文件名的字符串,得到表示目标文件的File。
//要在硬盘中准确地创建出一个文件,需要知道文件名和文件的目录。
2.4 将源文件的流拷贝成目标文件流,拷贝方法独立成为一个方法,方法的参数采用抽象流的形式。
//方法接受的参数类型尽量面向父类,越抽象越好,这样适应面更宽广。
}
分析listFiles方法内部的策略模式实现原理
File[] listFiles(FileFilter filter){
File[] files = listFiles();
//Arraylist acceptedFilesList = new ArrayList();
File[] acceptedFiles = new File[files.length];
int pos = 0;
for(File file: files){
boolean accepted = filter.accept(file);
if(accepted){
//acceptedFilesList.add(file);
acceptedFiles[pos++] = file;
}
}
Arrays.copyOf(acceptedFiles,pos);
//return (File[])accpetedFilesList.toArray();
}