Maorongrong smile like sunshine

Head first in Java

2015-10-14

其实感觉自己的成长完全是个野路子,try every way, then decide choose which way and many things just abort. don’t be like me !

从第16,17,18章开始不懂啦,以后慢慢补起来 对类、对象、实例解释:

类 是对某种事物的抽象概括,规定属性及方法 对象 是由某个类产生的具体实例,对类的属性及方法都给予具体的值 比如:由类CA生成对象ObjA,则说ObjA是类CA的一个实例。

语法

  • 加强版的for循环

从java5.0开始,Java语言就成为加强版的for循环,它能够很容易的逐个运行数组或其它集合的元素,如下图: QQ截图20150928144905.png-63.5kB 其他语言背景将这种循环有时称为:for-each或for-in循环。

  • 核心Java函数库(Java API) 可以翻阅参考书,推荐查看HTML API文档

  • 比较ArrayList与一般数组
    1. 一般数组在创建时就必须确定大小
    2. 存放对象给一般数组时必须指定位置(即指定索引)
    3. 一般数组使用特殊的语法 mylist[1]
    4. 在Java5.0中的ArrayList是参数化的(parameterized) ArrayList<String>String是类型参数,代表String的集合。
  • Java编程风格与命名规范整理 Java编程风格与命名规范整理原文出自【比特网】

  • 继承 1.当你调用对象引用的方法时,你会调用到与该对象最接近的方法。换句话说,最低阶的会胜出!
子类可以继承父类,也可以将父类方法“覆盖”,但要求覆盖不能改变父类方法的参数类型以及返回值类型要兼容;不能降低方法的存取权限。
子类也可以实现“重载”,即必须有不同的参数,返回值类型可以不同,可以更改存取权限。重载的意义是相同的方法名称,但是参数不同。重载与多态毫无关系。

2.父类不会使用子类的方法 如下图: 1.png-136kB 3.png-137.7kB

3.当子类把父类成员继承下来时会把它们当作是自己定义的一样。例如说当某个形状体继承Shape时,就会有rotate()和playSound()这两个方法。

任一类的成员包含有自己定义的变量和方法再加上从父类所继承下来的任何东西。 public类型的成员会被继承 private类型的成员不会被继承。

4.总结继承: 4.png-98.8kB 多态1.png-427kB

  • 多态

运用多态时,引用类型可以是实际对象类型的父类 通过多态,当你编出新型的子类时,也不必修改程序! QQ截图20150930094523.png-97.9kB

声明父类对象的数组后,运用多态,可以将数组的元素逐个调出来当作父类来操作。
//声明一个Animal类型的数组,也就是说一个会保存Animal类型对象的数组
Animal[] animals=new Animal[5];
//但是注意到这里,可以放任何Anmial的子类对象进去
animals[0]=new Dog();
animals[1]=new Cat();
animals[2]=new Wolf();
animals[3]=new Hippo();
animals[4]=new Lion();
for(int i=0;i<animals.length;i++){
//当i为0时候,这会调用Dog的eat()
    animals[i].eat();
//当i为1的时候,这会调用Cat的roam()
    animals[i].roam();
}

多态问答:

1.png-374.1kB

  • 抽象类 1.抽象类除了被继承之外,是没有用途,没有值,没有目的 >抽象类代表没有人能够创建出该类的实例。你还是可以使用抽象类来声明为引用类型给多态使用,却不用担心哪个创建该类型的对象,编译器会确保这件事。 可以赋值给父类的引用,即使父类是抽象类 2.抽象的类代表此类必须要被extend,抽象方法代表此方法一定要被覆盖。 >声明一个抽象的方法,就必须将类也标记为抽象的。

    22.png-203.8kB

  • Object类

在Java中的所有类都是从Object这个类继承出来的。 Object这个类是所有类的源头;他是所有类的父类。 没有被直接继承过的类会是隐含的继承对象 1.png-397.4kB

利用ArrayList可以实现多态引用,但是也有弊端: >当你把对象装进ArrayList时,不管它原来是什么,你只能把它当作是Object. 从ArrayList取出引用时,引用的类型只会是Object.这代表你只会取得Object的遥控器。如下图: 2.png-142kB

将ArrayList取出的对象恢复回原来的类型,如果确定对象是Dog类型

Object o=al.get(index);
Dog d=(Dog) o;//类型转换为Dog

如果不能确定他是Dog,可以使用instanceof这个运算符来检查,若是转换错了,会在执行期遇到ClassCastException异常而终止。

if(o instanceof Dog){
    Dog d=(Dog) o;
}

编译器是根据引用类型来判断有哪些method可以调用,而不是根据Object确实的类型

Java是很注重引用变量的类型,只能在引用变量的类确实有该方法时才可以调用它。

  • 接口

       接口方法带有public和abstract的意义。接口的方法一定是抽象的,所以必须以分号结束。记住,它们没有内容! 产生前提:为了某些原因实现“多个父类”这个主意有问题!这种“多重继承”可能会很差,因为会有**致命方块问题(如图)** ![3.png-95.9kB][11]
    

接口 interface关键词可以解决“致命方块问题”。办法如下:

把全部的方法设为抽象的!如此一来,子类就得要实现此方法,因此Java虚拟机在执行期间就不会搞清楚要用哪一个继承版本。
![4.png-168.3kB][12]

不同继承树的类也可以实现相同的接口!更棒的是类可以实现多个接口!!
  • 调用父类方法

    5.png-327.3kB

    7.png-358.4kB

构造器与垃圾收集器

  • 堆和栈

实例变量是被声明在类而不是方法里面,存在于所属的对象中。 不论对象是否声明或创建,如果局部变量是个对该对象的引用,只有变量本身会放在栈上,对象本身只会存在于堆上。 所有局部变量都存在于栈上相对应的堆栈块中。 对象引用变量和primitive主数据类型变量都是在栈上。

关于文件的读取与写入

public class FileReader extends InputStreamReader 用来读取字符文件的便捷类。此类的构造方法假定默认字符编码和默认字节缓冲区大小都是适当的。要自己指定这些值,可以先在 FileInputStream 上构造一个 InputStreamReader。 FileReader 用于读取字符流。要读取原始字节流,请考虑使用 FileInputStream。 举例如下:

1.png-26.2kB

对象的序列化与反序列化

序列化的文件很难让一般人阅读,但是比纯文本文件更容易让程序恢复对象的状态。

要让类能顾被序列化,就实现Serializable,该接口没有任何方法需要实现的。
如果某些实例变量不能或不需被序列化,将它声明为transient.

对象的输入与输出必须放在try块中

将序列化对象写入文件
//FileOutputStream将字节写入文件
FileOutputStream fileStream=new FileOutputStream("new File("MyGame.ser")");
//ObjectOutputStream将对象转换成写入串流的数据
ObjectOutputStream os=new ObjectOutputStream(fileStream);
//当调用ObjectOutputStream的writeObject,对象会被打成串流送到FileOutputStream来写入文件
os.writeObject(characterOne);
//关闭所关联的输出串流
os.close();
解序列化:还原对象
FileInputStream fileStream=new FileInputStream("MyGame.ser");
ObjectInputStream os=new ObjectInputStream(fileStream);
//读取对象,读取顺序与写入顺序相同,次数超过会抛出异常
Object one=os.readObject();
//返回的Object类型,因此需要转换类型
GameCharacter elf=(GameCharacter) one;
//关闭输入的串流
os.close();

### 文本文件的读与写入

1.写文本文件

写字符串
FileWriter writer=new FileWriter("Foo.txt");
writer.write("hello foo!");//以字符串做参数
writer.close();//记得要关掉

输入与输出相关操作必须包在try块中

2.读文本文件

用File对象表示文件,以FileReader来执行实际的读取,并用BufferReader来让读取更有效率。读取是以while循环来逐行进行,一直到readLine()的结果为null为止。

File myFile=new File("MyText.txt");
//FileReader是字符连接到文本文件的串流
FileReader fileReader=new FileReader(myFile);
//将FileReader链接到BufferedReader获取更高的效率,只会在缓冲区读空的时候才会回///头去磁盘读取。
BufferedReader reader=new BufferedReader(fileReader);

String line=null;
while((line=reader.readLine())!=null){
    System.out.println(line);//读一行显示一行,直到没有可读为止
}
reader.close();

3.Java.io.File

将File文件当做文件的路径,不是文件本身。举例:在构造函数中取用字符串文件名的类也可以用File对象来代替该参数,以便检查路径是否合法,然后再把对象传给FileWriter或FileInputStream。

//创建代表现在存盘文件的File对象
File f=new File("MyCode.txt");
//建立新的目录
File dir=new File("Chapter7");
dir.mkdir();
//列出目录下的内容
if(dir.isDirectory()){
    String[] dirContents=dir.list[];
    for(int i=0;i<dirContents.length();i++){
        System.out.println("dirContents[i]");
    }
}
//取得文件或目录的绝对路径
System.out.println(dir.getAbsolutePath());
//删除文件或目录(成功true)
boolean isDeleted=f.delete();

4.缓冲区的奥妙

通过BufferWriter和FileWriter的连接,BufferWriter可以暂存一堆数据,然后到满的时候再实际写入磁盘,可以减少磁盘操作次数
BufferedWriter writer=new BufferedWriter(new FileWriter(aFile));
强制缓冲区立即写入
writer.flush();

1.png-135.1kB

5.用String的split()解析

String的split()可以把字符串拆开为String的数组。
String toTest="Waht is blue+yellow?/green";
split()会用参数指定的字符把这个String拆开成两个部分
String[] result=toTest.split("/");
for(String token:result){
    System.out.println(token);
}

6.涉及到编码(GB2312\UTF-8)的文本文件的读与写

EUC-CN是GB2312最常用的表示方法。 当我们读写文本文件的时候,采用Reader是非常方便的,比如FileReader,InputStreamReader和BufferedReader。其中最重要的类是InputStreamReader, 它是字节转换为字符的桥梁。你可以在构造器重指定编码的方式,如果不指定的话将采用底层操作系统的默认编码方式,例如GBK等。 事实上在FileReader中的方法都是从InputStreamReader中继承过来的。read()方法是比较好费时间的,如果为了提高效率我们可以使用BufferedReader对Reader进行包装,这样可以提高读取得速度,我们可以一行一行的读取文本,使用readLine()方法。 转:Java的文件读写操作

try{
	File myfile=new File("myfile.txt");
    FileInputStream fileStream=new FileInputStream(myfile);
	InputStreamReader reader=new           InputStreamReader(fileStream,"UTF-8");//此处编码指的文本文件的原始编码
	BufferedReader bufferReader=new BufferedReader(reader);
	String str=null;

//	    //逐行读取,此处是将读到的文本显示在console上
//		while((str=bufferReader.readLine())!=null){
////		System.out.println(str);
////	}
// }catch (Exception ex){
//	 ex.printStackTrace();
// }
//		
//		

		//写文本文件
	File myOutFile=new File("F:\\workspace\\try\\myoutfile.txt");
	FileOutputStream fileoutStream=new FileOutputStream(myOutFile);
	//EUC-CN是GB2312最常用的表示方法
	OutputStreamWriter writer=new OutputStreamWriter(fileoutStream,"UTF-8");
	BufferedWriter buffeWriter=new BufferedWriter(writer);
	System.out.println(writer.getEncoding());

	//将myfile.txt读到的内容写入myoutfile		
	while((str=bufferReader.readLine())!=null){
		writer.write(str);
		writer.write("\n");//每行结束换下一行
		writer.flush();
	}
}catch (Exception ex){
	ex.printStackTrace();
}

Java指定编码读写文件(UTF-8)

已有更好的方法,详见 Java文件操作类FileManager

读取

    import java.io.BufferedReader;  
    import java.io.FileInputStream;  
    import java.io.InputStreamReader;  

    String FileContent = ""; // 文件很长的话建议使用StringBuffer
    try {
        FileInputStream fis = new FileInputStream("d:\\input.txt");
        InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
        BufferedReader br = new BufferedReader(isr);
        String line = null;
        while ((line = br.readLine()) != null) {
            FileContent += line;
            FileContent += "\r\n"; // 补上换行符
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

写入

    import java.io.FileOutputStream;
    import java.io.OutputStreamWriter;

    String FileContent = "文件内容";
    try {
        FileOutputStream fos = new FileOutputStream("d:\\output.txt");
        OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
        osw.write(FileContent);
        osw.flush();
    } catch (Exception e) {
        e.printStackTrace();
    }

类与类之间的包含图

12.jpg-66.1kB

Socket与ServerSocket

很赞的讲解:ServerSocket 用法详解

示例代码:

Server.java
==================================================
import java.net.*;
import java.io.*;

/**
 *  
 * 服务器端程序:
 *
 * 1. 监听一端口,等待客户接入;
 * 2. 一旦有客户接入,就构造一个Socket会话对象;
 * 3. 将这个会话交给线程处理,然后主程序继续监听。
 *  
 * @author OKJohn
 * @version 1.0
 */

public class Server extends ServerSocket {

    public Server(int serverPort) throws IOException {
        //用指定的端口构造一个ServerSocket
        super(serverPort);  
        try {
            while (true) {
                //监听一端口,等待客户接入
                Socket socket = accept();  
                //将会话交给线程处理
                new ServerThread(socket);  
            }
        } catch (IOException e)	{
    e.printStackTrace();
}
finally {
            close();  //关闭监听端口
        }
    }

    // inner-class ServerThread
    class ServerThread extends Thread {
        private Socket socket;
        private BufferedReader in;
        private PrintWriter out;

        // Ready to conversation
        public ServerThread(Socket s) throws IOException {
            this.socket = s;
              // 构造该会话中的输入输出流
            in = new BufferedReader(new InputStreamReader(
socket.getInputStream(), "GB2312"));
            out = new PrintWriter(socket.getOutputStream(), true);
            start();
        }

        // Execute conversation
        public void run() {
            try {

                // Communicate with client until "bye" received.
                while (true) {
                     // 通过输入流接收客户端信息
                    String line = in.readLine();  
                    if ("bye".equals(line)) {  // 是否终止会话
                        break;
                    }
                    System.out.println("Received message:" + line);
                    String msg = "'" + line + "'has been accepted by server.";
                  // 通过输出流向客户端发送信息
                    out.println(msg);
                    out.flush();
                }

                out.close();
                in.close();
                socket.close();

            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    // main method
    public static void main(String[] args) throws IOException {
        new Server(2000);
    }
}
Client.java
================================================
import java.net.*;
import java.io.*;

/**
 *  
 * 客户端程序
 *
 * @author OKJohn
 * @version 1.0
 */

public class Client {

    private Socket socket;
    private BufferedReader reader;
    private PrintWriter writer;

    public Client(int serverPort) {
        try {

            // 向指定服务器(IP、端口)发出请求
            socket = new Socket("127.0.0.1", serverPort);

            // 用得到的会话对象构造输入输出流
            reader = new BufferedReader(
                    new InputStreamReader(socket.getInputStream()));
            writer = new PrintWriter(socket.getOutputStream());

            // Communicate with server until "bye" input.
            while (true) {

                // 接受统标准输入(键盘)输入的信息
                BufferedReader in = new BufferedReader(
                        new InputStreamReader(System.in));
                String message = in.readLine();
                // 将信息通过输出流发送给服务器
                writer.println(message);
                writer.flush();
                // 是否终止会话
                if ("bye".equals(message)) {
                    break;
                }
                // 通过输入流接收服务器信息
                String received = reader.readLine();
                System.out.println(received);
            }

            writer.close();
            reader.close();
            socket.close();

        } catch (UnknownHostException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public static void main(String[] args) {
        new Client(2000);
    }
}

关于包、jar包与部署

如何打jar包

编写java程序,要学会在MyProject下创建src(source)与classes目录,并确保所有的类文件.class文件都在classes目录下。创建manifest.txt来描述哪个类具有main方法。该文件只有一行Main-Class:MyAppc,在次行后面要有换行,否则会出错。并将其放在classes目录下。

jar命令格式:jar {c t x u f }[ v m e 0 M i ][-C 目录]文件名…

其中{ctxu}这四个参数必须选选其一。[v f m e 0 M i ]是可选参数,文件名也是必须的。

-c 创建一个jar包 -t 显示jar中的内容列表 -x 解压jar包 -u 添加文件到jar包中 -f 指定jar包的文件名 -v 生成详细的报造,并输出至标准设备 -m 指定manifest.mf文件.(manifest.mf文件中可以对jar包及其中的内容作一些一设置) -0 产生jar包时不对其中的内容进行压缩处理 -M 不产生所有文件的清单文件(Manifest.mf)。这个参数与忽略掉-m参数的设置 -i 为指定的jar文件创建索引文件 -C 表示转到相应的目录下执行jar命令,相当于cd到那个目录,然后不带-C执行jar命令

数据结构

QQ截图20151223154553.png-173.8kB

1.List:对付顺序 ArrayList是个list,不能排序,但TreeSet或Collections.sort()可以排序。ArrayList实现了List接口,可以传给调用List的接口。

声明文件:
public class ArrayList<E>extends AbstractList<E>implements List<E>, RandomAccess, Cloneable, Serializable
E部分会用声明与创建的真正类型代替
ArrayList是AbstractList子类,且实现List接口,因此E类型会用在其上

2.Set:注重独一无二的性质,去重 TreeSet 3.HashMap 4.LinkedList 5.HashSet 6.LinkedHashMap

泛型

  • 创建被泛型化的类(例ArrayList)的实例
  • 声明与指定泛型类型的变量
  • 声明(调用)取用泛型类型的方法


Similar Posts

Comments