Java初学笔记

JAVA的性能高与低
低:
Interpreted,翻译式的语言
每执行一个程序前会进行Code Check,检查一遍代码是否有问题
Stack Machine,堆栈式的编译计算

高:
JIT,just in time,刚编译的程序不用再次编译
多线程
简单的命令代码设计 Byte code simple design

稳定与安全
1.没有指针 no point
2.Index check
数组有下标检查
3.Auto memory mangement  
JAVA中有new,没有delete,不用了就不理它,垃圾回收程序会帮你自动收集垃圾

JAVA原则:KISS,Keep It Simple Stupid.

JAVA = C++--
JAVA没有,C++有的:
多继承 Mutil-inheritance
虚继承 Virtual inheritance
模板 Template
符号重载 Operator overloading


JAVA没有传统的程序的概念
JAVA认为全世界的类和对象是一个空间
你写的程序的编译结果是这个空间的一部分
所谓的运行程序就是从空间中的某类的某个特殊的方法开始启动

Storage of objects
所有Java的类都必须new出来
For C,efficiency is the most important, so programmers can make decision by their own.
For Java, all objects should be constructed in runtime and be stored in heap存储在堆里.

Create and destory objects
You must create your objects.
But can not destory them by yourself.
There is a recycle mechanism to help clean up objects that will never be used again.
回收机制办断垃圾的原理是看是否还有人用着这个对象,当内存快用完的时候才检查。

Container
Is an object to hold other objects
eq. vector,stack,queue

root
Every class in Java is a descendant of one class: Object
So all objects in Java is objects of the class Object.
In this way, container is an object that can hold objects.

handel
You can not hold the object itself,instead,you can have a handle that refer to it.
String s; 此句表示s是一个String类的引用,s的对象并不存在。
Here s is only a handel that refer to nothing.

String s = new String("a string");
这句话做了4件事
1. An object of String is created
String的对象在堆里被创建
2. The object is initialized w/"a string"
这个对象被初始化
3. A variable as handle to String is created
一个指向String类的引用被创建
4. The value of handle variable is assign to object
这个引用指向这个对象

命名规则
第一个字母大写表示类,as CoolBoy
第一个字母小写表示函数,as helloWorld


基本数据类型不是对象
如boolean,char,byte,int,long,float...
Java中没有无符号的数,no unsigned

Java中的方法只能作为类的一部分创建

Integer n1 = new Integer(47);
Integer n2 = new Integer(47);
System.out.println(n1==n2);  // false
Systme.our.println(n1!=n2);  // true
n1,n2都是引用,是指向类的指针,由于指向不同的类所以两者结果不同

编译单元
每个编译单元必须是以.java结尾的文件名称,在一个编译单元里,可以有一个public的类,这个类的名字必须与文件的名字相同。在一个单元内,只能有一个public的类。
编译一个.java文件时,对应于文件中的每个类,会得到一个.class文件,文件名与类的名字相同。一个程序是一堆.class文件。

定义包
一个库是一堆这样的.class文件,它们被定义为一个包,但是并不真正的合并在一个文件中。
package mypackage;

CLASSPATH
将某个特定的包使用的所有.class文件都放在一个目录下。
CLASSPATH包含一个或多个目录,它们作为一种特殊的根使用,从这里展开对.class文件的搜索。
-自动编译
-冲突
-Classpath的陷阱


类成员的访问属性
如果没有加public,protected,private
则是friendly(缺省包,同一package可访问)
public:界面访问
private:不能接触!
protected:某种友好,继承

一个编译单元没有一个public类,所有的类都是friendly的,那么文件名可以任意起


final data
变量只能被附一次值

final methods
有两种final方法:
1.在方法上加一把锁,防止继承者改变它的意义。
2.编译器把对该方法的调用变成inline调用。
private is final

final classes是不允许被继承的。


抽象类和抽象方法
一个类的作用仅仅是表达接口,而不是具体的实现细节。
抽象的方法是不完全的,它只是一个申明,没有方法体。
包含一个抽象方法的类被称作抽象类。
不能制造抽象类的对象。
从抽象类继承的类必须override所有的抽象方法,否则它自己成为一个抽象类。
可以申明一个抽象类但是里面没有一个抽象方法。

Interface
is totally abstract class
This is what all classes that implement this particular interface will look like.
public interface InterfaceName extents BaseInterfaces
在interface中所有的方法都是public的,即使你没有申明它是public的。
在interface中所有的数据成员都是public static final的,即使你没有申明。但不能是blank final


实现interface
实现interface的类,其interface中所有的方法必须被“实现”,否则这个类成为一个抽象类。
所有实现interface中的方法必须被申明为public.
Interface可以从多个interface得到继承,但是不能继承类。
一个类可以实现多个interface.


Inner class内部类
It is possible to place a class definition within another class definition.
Inner classes可以完全地被封闭起来,不被外界看到。


Why inner classes?
两个理由要在方法和scope中定义inner class:
1.我们准备实现某种形式的interface,使自己能创建和返回一个句柄。
2.要解决一个复杂的问题,并希望创建一个类,用来辅助自己的程序,同时不愿意把类的细节公开。

inner classes拥有访问外部类所有成员的能力


//----------------------------------------------------------------------
//父类与子类之间的秘密--------example 1------------------
//----------------------------------------------------------------------
class Base
{
    int i=47;
    int f() {return i;}
}
class Derived extends Base
{
    int i=27;
    int g() {return i;}
}
public class Test
{
    public static void main(String[] args)
    {
        Derived d = new Derived();
        System.out.println(d.f());
        // print: 47
    }
}


//----------------------------------------------------------------------
//父类与子类之间的秘密--------example 2------------------
//----------------------------------------------------------------------
class Base
{
    int i=47;
    int f() {return g();}
    int g() {return i;}
}
class Derived extends Base
{
    int i=27;
    int g() {return i;}
}
public class Test
{
    public static void main(String[] args)
    {
        Derived d = new Derived();
        System.out.println(d.f());
        // print: 27
    }
}


//----------------------------------------------------------------------
//父类与子类之间的秘密--------example 3------------------
//----------------------------------------------------------------------
class Base
{
    int i=47;
    int f() {return g();}
    private int g() {return i;}
}
class Derived extends Base
{
    int i=27;
    int g() {return i;}
}
public class Test
{
    public static void main(String[] args)
    {
        Derived d = new Derived();
        System.out.println(d.f());
        // print: 47
    }
}



Exception
The basic philosophy of Java is that "baddy-formed code will not be run".
总有一些问题是编译时刻预计不到的readfile;
能否很好地处理运行时刻的异常情况是程序健康的标志
中国程序员普遍缺乏异常处理意识
用户都知道软件没有不出错的,所以要把运行错误报告给用户,而不是试图隐藏

Throw an exception
throw new NullPointerException();
throw new NullPointerException("HERE!");
异常发生时,你不能解决问题,所以必须扔(throw)出一个异常。
1.一个异常对象建立起来了。
2.当前运行的路径被停止,异常对象被弹出(eject)。
3.异常处理机制接管,开始寻找一个合适的地方来继续执行。

Java的异常机制的好处就在于它使我们在一个地方将精力集中在要解决的问题上,而在另一个地方处理来自那部分代码异常情况。
try{    //Code that may make exception
} catch (Type1 id1) {
} catch (Type2 id2) {
}

匹配异常不需要精确匹配

一个捕捉任何异常的捕捉器是一个捕捉基本类型异常的捕捉器。
catch(Exception e){
    System.out.println("caught an exception");
}

Exception的接口
Interface: Throwable  
String getMessage();
String toString();
void printStackTrace();
void printStackTrace(PrintStream);


Announce for exception
通知客户程序员自己写的方法中可能抛出什么样的异常是一种文明的做法。
void f() throws tooBig,tooSmall,oldStyle
{    //Body of f()    }
如果你要从你的方法中抛出某种异常,你必须申明。
但是你可以撒谎申明你并不是真正抛出的异常。


Override of exception
当你override一个方法,你只能申明和抛出不比它的父类版本中申明的异常多的异常。


finally
异常处理中必须被执行的代码


Run-time exception
Run-time exception不需要主动throw
Run-time exception不需要申明
如果一个run-time exception被系统throw后没有被catch,会导致程序终止,并printStackTrace()


Java IO System

InputStream (abstract class) 处理byte文件
read()
int read()
read(byte b[])
read(byte[],int off,int len)
skip(long n)
int available()
mark()
reset()
boolean markSupported()
close()

OutputStream
write()
write(int b)
write(byte b[])
...

所有的IO操作都有可能抛出异常

Kinds of InputStream
ByteArrayInputStream
StringBufferInputStream
FileInputStream
PipedInputStream
SequenceInputStream

Filtered Stream
DataInputStream        -    DataOutputStream
LineNumberInputStream    -    PrintStream
BufferedInputStream    -    BufferedOutputStream
PushbackInputStream


Object Serialization对象串行化
把任何实现了Serializable接口的对象转化成一串字节,这串字节以后可以还原为原来的对象——persistence
Java引入对象串行化是为了实现两个特性:远程方法调用(RMI)和Java Beans.
为了串行化一个对象,首先建立一个ObjectOutputStream对象;然后就可以向这个流writeObject()。为了恢复一个对象,建立一个ObjectInputSteam,使用readObject()。


创建一个线程
创建一个线程就是创建一个新的虚拟CPU(virtual CPU),让它去运行一段代码。
1.定义一个类,实现Runnable接口,并override run()方法,在这个方法里是你希望这个线程运行的代码。
2.创建一个这个新类的对象。
3.创建一个Thread类的对象,用刚才的Runnable对象作为构造函数参数。
4.调用Thread对象的start()方法来启动线程。

控制线程
start()
stop()
suspend()
resume()
Thread.sleep() 哪个线程执行了sleep,那个线程就sleep
join() 等待另外一个线程运行结束
Thread.yield() 放弃运行状态,转为ready状态

class MethodTest {
    public static void main(String[] args) {
        FirstThread first = new FirstThread();
        SecondThread second = new SecondThread();
        first.start();
        second.start();
        try {
            System.out.println("Waiting for first thread to finish.");
            first.join();
            System.out.println("It's a long wait!");
            System.out.println("Waking up second thread..");
            second.resume();
            System.out.println("Waiting for second thread to finish.");
            second.join();
        } catch (InterruptedException e) {
        }
        System.out.println("I'm ready to finish too.");
    }

    class FirstThread extends Thread {
        public void run() {
            try {
                System.out.println("First thread starts running.");
                sleep(10000);
                System.out.println("First thread finishes running.");
            }
            catch (InterruptedException e) {
            }
        }
    }

    class SecondThread extends Thread {
        public void run() {
            System.out.println("Second thread starts running.");
            System.out.println("Second thread suspend itself.");
            suspend();
            System.out.println("Second thread runs again and finish.");
        }
    }
}



线程运行中信息
Thread.currentThread()
getName()
getThreadGroup()
getPriority()
isAlive()
isDaemon()


线程交互
在一些关键状态下,别的线程不能接触数据。这种关键状态下的代码称为critical section.

Synchronized Section
synchronized(object){//}
钥匙在对象中,而不在代码中。
1.每个对象有一个钥匙
2.为了执行synchronized()块,线程需要得到对象中的钥匙。一旦获得了钥匙,对象就不再拥有钥匙。
3.如果当线程要执行synchronized()时,钥匙不在对象中,线程就stall了。一直到钥匙还到了对象中,才被这个线程拿到。
4.当线程离开synchorized()块,钥匙就还给了对象。


How to 保护数据?
synchronized()并不是保护数据不被访问,只是保证同一时刻只有一个线程在运行。
1.数据私有
2.所有的访问都同步化
3.用数据本身做钥匙


嵌套同步
如:
sychn..(a) {
    sychn..(a) {
    }
}
Java中嵌套同步是安全的
同步化方法
-void method(){
    synchronized(this){//}
}
等于
synchronized void method() {//}


死锁 Dead lock

死锁dead lock
饿死starvation

死锁出现的情况
sychn..(a) {
    sychn..(b) { }
}

sychn..(b) {
    sychn..(a) {
    }
}


线程间通讯
PipedInputStream/PipedOutputStream

通讯的一般方法
To define a data in sender and the receiver read the data. There must be a flag to indicate the data is valid or has been read.

Wait() & notify()
wait() and notify() of Object
Every object can have a thread pool. A thread can call wait() to join the pool and call notify() to leave the pool.
线程一旦执行wait(),则如果掌握着钥匙,就把钥匙还掉
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值