Head First Java学习笔记

1.基本概念

1.1.工作方式

   源代码(.java)---编译器(执行javac程序)---产生字节码(.class与平台无关)---JAVA虚拟机(JVM,读取与执行字节码)

1.2.汇编语言是对基础机器的少量抽象,C,BASIC,FORTRAN等是对汇编语言的一种抽象

1.3.类实例化的过程相当于创建了一个句柄

1.4.doStuff(c),一个圆句柄传递给一个本来期待shape句柄的函数,圆是shape的子类,所以doStuff()发给shape的消息,circle也能接受,原因是编译器编译代码时并不知道自己要操作的准确类型是什么,这种情况叫多形性,实现的方法叫叫动态绑定

1.5.用户提交的信息通过所有WEB服务器均能支持的“通用网关接口”(CGI)会传到服务器

1.6.数据保存地:

   1.6.1.寄存器

   1.6.2.堆栈(RAM,保存句柄)

   1.6.3.堆(RAM,保存对象)

扫描二维码关注公众号,回复: 1945832 查看本文章

   1.6.4.静态存储(RAM,static)

   1.6.5.常数存储(ROM)

   1.6.6.非RAM存储(另一台机器或磁盘,不依赖于程序是否运行)

1.7.实例变量数字默认值为0,BOOLEAN初始值为false,对象引用为null,局部变量没有默认值,必须初始化

2.构造器与垃圾收集器

2.1.正在执行的方法位于栈顶,执行完被释放掉

2.2.对象存在于堆中,实例变量存在于所属对象中,局部变量和方法的参数的生命周期只限于方法被放在栈上的这段期间,即所有局部变量存在于栈上的堆栈块中

2.3.primitive主数据类型变量指boolean,    char, byte,short,int,long,float,double这8种

2.4.对象引用变量与primitive主数据类型变量都是放在栈上

2.5.方法的参数传递都是值传递,基本类型传值,引用类型传地址

2.6.内存分两种,堆内存和栈内存

2.7.数组和对象在没有引用变量指向它的时候,才变成垃圾,不能再被使用,但是仍然占着内存,在随后的一个不确定的时间被垃圾回收器释放掉。这个也是java比较占内存的主要原因

2.8.堆和栈由JVM自带的机制进行管理

2.8.实例变量存在于对象所属的堆空间上,如果实例变量是个对象,则会在当前对象的堆空间中存入对象的引用变量,被引用的对象在被NEW的时候放在另一个堆空间中

2.9.内存分配策略:

   静态

   堆

   栈

2.10.无参构造函数是必须的(没有建的时候系统提供,自己写了构造函数的话则必须自写无参构造函数)

2.11.执行NEW的指令是个重大事件,它会启动构造函数连锁反应,一直到Object这个类为止,创建子类,其继承的父类也会被连锁创建,创建对象时其构造函数被逐次放到堆栈块,逐级调用直到最上面是Object类的构造函数

2.12.如果新建子类对象时,在子类的构造函数中没有写对父类构造函数的调用,则编译器会自动帮我们加上super(),对super()的调用默认会加在第一行,自写的话也必须保证在第一行

2.13.使用this()来从某个构造函数调用同一个类的另外一个构造函数,只能用在构造函数中,且必须是第一行语句,super()与this()不能兼得

2.14.方法运行于堆栈

2.15.局部变量在方法执行时存活,方法执行完死掉,活着的时候状态会被保存

2.16.有3种方法可以释放对象的引用

引用离开它的范围,如函数中有实例化,函数执行结束后

引用被重新赋值到其他对象上

引用被重新赋值为null

对象的引用死掉后,该对象就等着垃圾处理器回收了

2.17.静态方法直接从类调用,没有对象的引用,抽象的类是不能被初始化的

2.18.可通过用私有的构造函数来限制非抽象类被初始化eg:Math

2.19.静态方法不能调用非静态的变量,因为静态方法通过类名称来调用,所以无法引用到该类的任何实例变量,因为静态方法不知道堆上有哪些实例

2.20.静态方法也不能调用非静态方法,即使可以通过引用变量调用静态方法,但静态方法依然不知道是哪个对象引用所做的调用

2.21.同一类所有的实例共享一份静态变量,即可以用静态变量来统计某个类被创建实例的个数

2.22.静态变量的默认值为该变量类型的默认值

2.23.JVM决定什么时候加载类

2.24.final的类不能被继承,final方法不能被覆盖,final变量不能被改变值

2.25.primitive数据类型与对应的包装类型编译器会自动进行转换,即某处用到某种类型都可用其对应的类型替代

3.异常处理

3.1.编译器会核对每件事,除了RuntimeException之外

3.2.判断某个方法可能会抛出异常的方法是看该方法有没有throws Exception,那么其他方法在调用该方法时就要声明try/catchl

3.3.try/catch块种发生异常后,try后的语句不再执行,执行完catch后整个try/catch块后接着执行

3.4.try块失败---catch块---finally块---其余部分

   try块成功---finally---其余部分

   有return指令情况下流程会跳到finally然后再回到return指令

3.5.如果可能有多个异常,就要对应多个catch块,但通常通过声明多个异常的父类来代替声明多个异常

3.6.在调用可能出现异常的方法时,该方法也可以抛出异常(throws Exception),那么这个方法从堆栈上释放掉,异常抛给调用它的方法,如果主方法也抛出异常,最终异常会抛给JVM,JVM无法处理死掉

3.7.内部类可以使用外部所有的方法与变量,就算是私用的也可以,内部类跟正常的类没有差别还多了特殊的存取权,在外部类可以创建内部类的实例,如果要在外部类以外的程序初始内部实例,需要:

   Outer ot=new Outer();

   Outer.Inner in=ot.new Inner();

3.8.如果某类可序列化,则它的子类也可序列化

3.9.被标记为trasient的变量跳过实例化,静态类不会被序列化,序列化的类需要实现Serializable接口

3.10.序列化:链接(此处FileOutputStream叫做连接串流)

ObjectOutputStream os=new ObjectOutputStream(new FileOutputStream(a.ser))

os.writeObject(one);

os.writeObject(two);

...

解序列化:链接,读取的顺序必须与吸入的顺序相同

ObjectInputStream is=new ObjectInputStream(new FileInputStream(a.ser))

One one=(One)is.readObject();

    Two two=(Two)is.readObject();

    ...

3.11.某类被序列化,则它的引用对象也会被序列化

3.12.缓冲区bufferedWriter

    BufferedWriter bw=new BufferedWriter(new FileWriter(aFile))

bufferedWriter可以暂存一堆数据,等缓冲区满时再写入磁盘,这样就减少了对磁盘的操作次数,提高了效率,因为每趟磁盘操作都比内存操作话费更多的时间,如果要强制缓冲区立即写入,可调用bw.flush()这个方法

3.13.所有的流都是以下4个基本类的子类:

InputStream  Reader

OutputStream  Writer

InputStream和OutputStream及其子类处理字节流,按ASCII编码,主要用在处理二进制数据

字符流常用于文本

4.网络与线程

4.1.Socket连接(客户端对服务器建立)

   Socket a=new Socket(“11.1.45.234”,5000)

   网页服务器(HTTP)端口是80,HTTPS:443 这是规定的标准

4.2.每个服务器有65536个TCP端口(0-65535),0-1023都被保留给已知的特定服务

4.3.字符流与字节流通过InputStreamReader,OutputStreamWriter来关联,实际上是通过byte[]和String来关联

4.4.从Socket得到的输入流为字节流

4.5.PrintWriter可作为字符数据与字节间的转换桥梁

4.6.服务器对特定端口创建:

   ServerSocket serverSock=new ServerSocket(4242);

 服务器会监听4242这个端口

  客户端创建

  服务器创建与客户端通信的新Socket

 A.Socket sock=serverSock.accept();  (方法在用户连接时返回Socket)

服务器会无限循环,每次循环会调用A方法,A检测到客户端连接了才会继续往下执行

4.7.JAVA.LANG是被默认导入的

4.8.JAVA虚拟机会负责主线程的启动以及垃圾收集所需的系统用线程

4.9.只有多处理器才能同时处理好几件事

4.10.线程调用start()方法后,进入待执行状态,由虚拟机的线程调度机制来决定线程的状态

4.11.  GUI:图形用户接口

4.12.创建新线程(2中方法)

    A:实现Runnable接口

Runnable r=new MyRunnable();

Thread t=new Thread(r);

T.start();

B:用线程的子类覆盖掉run()方法

Class A extends Thread{

  @Override

  Void run(){......}

}

A a=new A(...)

A.start();

4.13.Thread.sleep()可以强制线程进入等待状态直到过了设定时间为止,sleep()(可能跑出异常)可以让所有线程都有机会运行

4.14.使用synchronized关键词可以防止两个线程同时进入同一对象的同一方法

4.15.每个对象有唯一的锁和钥匙,当使用同步化方法时,对象会在某个线程进入后锁上,别的线程企图进入就得等待

4.16.由于锁机制,两个线程在进入各自对象后睡觉醒来后访问对方的对象就都得处于等待状态,造成死锁

4.17.类本身也有锁,比如静态变量的保护

4.18.通过私有的构造函数和创建静态实例可做出单例模式

5.数据结构

5.1.对象被system.out.println()时会调用toString()方法

5.2.几乎所有以泛型写的程序都与处理集合有关

5.3.public <T extends Animal> void takeThing(ArrayList<T>  list)

   =

   public void takeThing(ArrayList<? extends Animal > list)

   表示任何被声明为Animal或Animal子类的ArrayList是合法的

   public static <T extends Comparable<? super T>> void sort(List<T> list)

   Comparable是个接口,以泛型的观点,extend代表extends或implements

5.4.hashCode()使用杂凑算法对heap上的对象产生独特的值,不同的对象有可能产生相同的值

6.,jar存档文件和部署

6.1.javac -d 目标目录  源文件(.java)

   可生成class文件到指定目录

6.2.jar工具可以从命令栏创建和执行JAR

7.分布式计算

7.1.目前接触的大部分方法都是对运行在相同JAVA虚拟机的对象进行的,即调用方与被调用方在同一个堆上

7.2.JAVA远程程序调用RMI(Remote Method Invocation)

7.3.远程方法的参数必须是primitive或serializable类型,任何远程方法的参数和返回值都会被打包通过网络传送,这是通过序列化完成的

7.4.远程接口要继承Remote且要声明异常,远程实现要继承UnicastRemote和实现远程接口(最简单的方式),产生stub和skeleton文件,启动远程服务,远程服务对象必须要向

RMI registry注册,Naming.rebind()绑定

7.5.客户端以Naming.lookup()查询远程服务

7.6.一般的servlet是继承httpServlet的类并覆盖掉doGet(),doPost()方法

7.7.WEB服务器会根据用户请求来启动并调用servlet上对应的方法,servlet可通过doGet()的响应参数取得输出串流来组成响应的网页

7.8.servlet是写出带有HTML输出的类,JSP是写出带有JAVA程序的网页,WEB服务器最终会把JSP转换成servlet,如果用servlet会出现一堆难以阅读的print命令

7.9.String s=”0”;

   For(int i=1;i<10;i++){

    s=s+i;

}

最后会建立10个String,建立行的String时,会被放入String pool中,不受垃圾收集器管理,浪费内存

7.10.IDE:集成开发环境

7.11.需要外部类的实例才能取得内部类的实例
7.12.传参的时候可以直接传类的定义

猜你喜欢

转载自www.cnblogs.com/qw870602/p/9279664.html