你的位置:首页 > Java教程

[Java教程]Java复习笔记


     最近要做两个基于JavaWeb的网络系统,想起我那渣得可怜的Java功底。。。泪崩!于是花了三天时间大体上上复习了一下java的重要知识,mark一记。

     目录

     一.基础知识

     二.string 

     三.类

     四.管理

     五.泛型

     六.线程

     七.反射

 

一.基础知识

     1.Java SE 可以分为四个主要的部分:JVM、JRE、JDK和Java语言。

   2.

 

     3.

 

二.string

     1.java中字符串不仅仅是字符数组,还是string类的一个实例。

     2.静态分解方法parseByte(),parseShort().parseInt().parseLong(),parseFloat(),parseDouble()

=>NumberFormatException异常

   3.使用索引取得字符串

     4.字符串内容不可变(不是原来的字符对象了)

     5.Java执行时会维护一个string池(pool)。如string str=”aa” ;str0=”aa”;   那么str==str0(引用自同一个对象)

     Intern()  :先equals() pool中的内容,有相同则返回池中对象的引用

     Eg: String str1=new String(“aa”); String str2=new String(“aa”);str1.equals(str2);

一共产生了三个string实例。”aa”本身一个,存在于pool中,又new两个String对象,分别由str1和str2参考

   6.StringBuilder类,默认16字符长度,会自动增加长度以荣内被附加的字符

     单机非多线程:StringBuilder

     StringBuffer处理同步,多线程

   7.分离字符串 split()

 

     8.正则表达式

     运行原理:

     Matches()  pattern的静态方法,返回boolean(),表明字符串是否符合正则表达式。

     将正则表达式作为一个对象重复应用,使用pattern的静态方法compile()进行编译,返回pattern的一个实例,然后可以重复使用实例的matcher()方法

     Pattern  pattern=Pattern.compile();

     Matcher  matcher=pattern.matcher();

     显示 matcher.group()

 

三.类

 

  1. class关键字定义类,用类定义对象。一个文件中只能有一个类被设定为public,且文件名同类名
  2. 与类同名的方法称为构造函数,一般用来初始化(一般为public,可有多个,不同的参数arg)
  3. 方法中的变量名称会暂时覆盖域成员的作用范围(内层优先于外层)
  4. This用来引用自调用方法的实际对象,也可以带参数用来调用构造函数,而避免直接以构造函数的名称来调用。
  5. Static所有类所有,不能有this,java的静态方法中不允许使用非静态成员
  6. Java在使用到类的时候才会加载类到程序中,如果希望在加载类时先进行一些类的初始化工作,可以使用使用static定义一个静态区块,会在加载时被先加载,且仅加载一次。
  7. 返回值的类型不能作为方法重载的区别依据。
  8. 编译器在处理重载方法、装箱问题和不定长度参数时,依照以下顺序:

 

     (1) 没有装箱动作前可以符合参数个数和类型的方法

 

     (2) 装箱动作后可以符合参数个数和类型的方法

 

     (3) 不定长度参数并可以符合的方法  eg: int sum(int...nums){ for(int sum:nums){ }},实际为传入参数为int[] nums

 

     (4) 找不到对应的方法,报告错误

 

     9. 垃圾收集

 

     10.extends  public成员可以直接在子类中被调用使用

     11.在扩展了某个类以后,可以用supeer()基底类的构造函数。在子类的的构造函数中,如果不用super(),默认调用父类的无参构造函数。

 

     12.protected 派生类(子类)可以直接存取基类中的成员,而不会被外部对象获取。

     13.object的toString()默认返回类名称和十六进制编码:getClass().getName()+’@’+Interger.toHexString(hashCode())。可以被重写。

Equals()本身是比较对象的内存地址是否相同。重写equals()时需要同时重写hashCode()。因为在以hash码为基础的相关环境中,需要比较两个对象是否为相同的对象时,除了使用equals(),还会使用hashCode()方法。

     14.clone()方法,复制对象本身。要支持复制自身的对象,定义类的时候必须实现Cloneable接口,不然其实例的clone()方法被调用时,会抛出CloneNotSupportedException。

     15.多态:使用共同的实现接口(通常指的是在类上定义的公开方法),以实现不同的对象实例。为了降低对实现接口的依赖程度。Java在实现多态时,可以让程序依赖于抽象类或接口。Abstract  extends

     接口的目的在于定义一组可实现的方法,实现某接口的类必须实现该接口的所有方法,只要对象有实现某个接口,就可以通过该接口实现对象上对应的方法。 Interface implement

 

 

 

     每多实现一个接口,就多遵守一个实现协议。类一次只能继承一个父类,但一个接口可以同时继承多个父接口。(以I开头定义)

 

四.管理

     1.相关:静态工厂,Iterator

 

     2.一个.java文件中只能有一个public类,没有被声明为public的类只能被同一个包中类的实例调用。如果申明类的时候不使用public等,则预设为包存取范围。

     3.异常:在Java中代表一个错误的实体对象。最好只用于错误处理,而不用于业务逻辑的一部分,因为异常产生消耗资源。

Try(唯一)必有  catch(不一定唯一)和finally(唯一)至少取其一。

 

 

     父类的某个方法声明抛出异常,重写该方法时:可以不处理,仅抛出父类中被抛出的某些异常,抛出父类被抛出异常的子类。不能抛出父类方法中未定义的其它异常,不能抛出父类抛出异常的父类。

     4.断言 Assertion 预期程序处于某种状态。默认启动时不检查,除非使用-enableassertions或者-ea自变量。

Assert boolean_expression;        false抛出java.lang.AssertionError

Assert boolean_expression:detail_expression;   false 显示detail_expression

     5.枚举类型是一种特殊的类 成员为实例,被默认修饰为final public static.可以构造非公开的构造函数(Singleton模式的应用)

 

五.泛型

     1.J2SE5.0之前使用Object定义类并转换为原来的类型或者适当的接口。

有了泛型之后,使用<T>声明一个类型持有者名称。使用泛型所定义的类在声明及配置对象时,可以使用尖括号一并指定泛型类持有者T的真正的类型,而不需要类型或接口转换。

     2.可以使用泛型来声明一个数组,但是不能使用泛型来建立数组的实例。

     3.限制泛型可用类型  同时使用extends指定这个类型持有者实例化,实例化的对象必须是扩充自某个类型或实现某接口。

     4.类型通配符(Wildcard)   ?代表未知类型,并用extends关键词来限定(无法加入新类型,只能取或者移除)

<? Extends someClass> 向下限制   只能是包含在内的,或者子类

<? Super someClass>   向上限制   只能是包含在内的,或者超类

     5.扩充泛型类和实现泛型接口   建议:父类的类型持有者都要保留

 

六.线程

     1.进程是一个包含自身执行地址的程序。RR轮转法。可以包括多个线程,即线程的执行流程,由于RR的时间片短,所以程序看起来像同时进行多个不同的子流程。

     2.JAVA中实现线程,可以继承java.lang.Thread类,并重新定义run(),自后范例化自定义的Thread类,再使用start()启动线程。

     或者实现java.lang.Runnable接口来定义含有线程功能的类。Runnable接口中定义有一个run()方法,在范例化一个Thread对象时,可以传入一个Runnable接口的对象作为自变量,Thread对象会调用Runnable对象的run()方法,进而执行其中所定义的流程。

     3.java中一次只能继承一个类。

     4.如果希望某个线程在产生它的线程结束后也跟着终止,则设定它为Daemon线程,在后台执行服务。setDaemon()方法。

     5.

 

     范例化一个Thread并执行start()后,线程进入Runnable状态(可执行准备状态),等待调度。setPriority()方法设定线程的优先级(1~10,默认为5)。同优先级则RR。

     6.对于不支持Timeslicing的系统,让目前线程礼让其它线程(暂停,进入Runnable状态),用yield(js类比)。

 

     7.join()中途插入一个 高优先级(先执行)的线程。

     8.ThreadGroup线程组。判断:Thread.currentThread().getThreadGroup().getName()。

     9.处理Unchecked exception,J2SE5.0之前用uncaughtException(),之后使用Thread.UncaughtExceptionHandler接口,并实现其uncaughtException()方法。

     10.同步synchronized。不同线程共享数据的时候,同时更新同一对象信息时。

     11.每个对象内部都会有一个锁定,被标识为synchronized的方法会成为同步区域,当线程执行某个对象的同步区域时,要执行同步区域的线程,都必须先获得对象的锁定,执行完同步区域之后再将锁定归还给对象。由于对象的锁定只有一个,因此一个线程取走锁定在执行同步区域的代码时,其它想执行synchronized区域的线程在锁定池等待,直到归还为止。获得锁定的线程才能进如Runnable状态等待调度。

 

     12.wait(),必须在同步的方法或者区块中,要求线程进入对象的等待池。

     Notify()从等待池中通知一个线程加入到锁定池的Blocked状态,被通知的线程是随机的,且会与其它线程共同竞争对象的锁定。(生产者模式)

     13.容器内默认没有考虑线程安全问题,必须自行实现同步。可以使用java.util.Collection的synchronizedXXX()等方法传回一个同步化的容器对象。以这种方式返回的对象,在使用Iterator遍访对象时,仍必须实现同步化。J2SE 5.0后再java.util.concurrent里面有一些确保线程安全的类。

     14.JDK1.2之后可以给予每个线程一个特定的空间来保管该线程所独享的资源,使用java.lang.ThreadLocal。

     15.util.concurrent.Callable与util.concurrent.Future协助完成future模式,在请求发生时,先产生一个Future对象给发出请求的客户,类似代理,同时所代理的真正目标对象的生成是由一个新的线程持续进行。

     16.

 

     17.

 

七.反射

     1.可以通过Object的getClass()方法来取得每一个对象对应的Class对象,或者通过class常量,在取得class对象之后,就可以操作class对象上的一些公开方法来取得类的基本信息。

     2.Java仅在需要使用类的时候才会加载,如在用new生成对象时,声明参考名称并不导致类被加载。一个类在JVM中只会有一个Class实例,且以实例的形式存在。基本类型也都有对应的Class对象。

     3.在无法事先知道用户将加载什么类,而必须让用户指定类名加载类的时候,可以用Class的静态forName()方法实现动态加载类。指定类名称,甚至指定加载类时是否运行静态区块,指定类加载器。

     4.

 

     5.命令模式执行java XXX.class指令

     =>java运行程序查找JRE安装目录

     =>找jvm.dll(默认为bin\client)

     =>启动jvm并进行初始化动作

     =>产生Bootstrap Loader(一般由C编写而成)

     =>Bootstrap Loader(一般为java编写而成)加载Extended Loader,并设置其parent为Bootstrap Loader

     =>Bootstrap Loader会加载System Loader,并设置System Loader的parent为Extended Loader

     =>System Loader开始加载指定的类

     每一个加载器会先将加载类的任务交给其parent,如果parent找不到,再由自己负责加载。即Bootstrap => Extended Loader => System Loader =>NoClassDefFoundError

 

 

Java类加载器层次架构

 

     (1)Bootstrap Loader会搜索系统参数sun.boot.class.path中指定位置的类(默认为JRE下classes中的.class文件或lib下的.jar文件),可以使用System.getProperty(“sun.boot.class.path”)查看。

     (2)Extended Loader会搜索系统参数java.ext.dirs中指定位置的文件(默认为JRE目录下的lib\ext\classes下的.class文件或lib\ext下的.jar文件),可以使用System.getProperty(“java.ext.dirs”)查看。

     (3)System Loader 会搜索系统参数java.class.path中指定位置的文件(默认为当前工作目录下的.class文件),可以使用System.getProperty(“java.class.path”)查看。

     (4)三个加载器各司其职,文件放错位置会抛出异常或null。

     6.使用loadClass()方法加载类的时候,不会运行静态区块。

     7.ExtClassLoader和AppClassLoader都是java.net.URLClassLoader的子类。在程序启动后两者都会在虚拟机中存在一份,程序运行时无法再改变它们的路径,需要动态加载其它路径的类则需要产生新的加载器。

     指定ExtClassLoader的搜索路径 java -Djava.ext.dirs=c:\路径

     指定AppClassLoader的搜索路径(设置ClassPath) java -classpath c:\路径

 

    使用URLClassLoader来产生新的加载器。

     URL url=new URL(“file:/c:/路径”); 

     ClassLoader urlClassLoader= new URLClassLoader(new URL[] {url});

     Class c=urlClassLoader.loadClass(“SomeClass”);

     8.BootStrap Loader载入ClassLoader

=>新增了ClassLoader实例 (自动将其parent设置为AppClassLoader) 后,使用loadClass()来指定要加载的类

     9.使用反射机制,可以在运行时期动态加载类并生成对象,操作对象上的方法,改变类成员的值,甚至于改变私有变量的值。

     10.newInstance()=>实例化对象,返回Object类型

指定参数类型,去的Constructor对象,使用Constructor的newInstance()并指定参数的接受值=>动态加载及生成对象时指定对象的初始值

     11.J2SE 1.3之后加入java.lang.reflect.Proxy类,可协助实现动态代理功能。

     实现动态代理功能=>

     定义要代理的接口=>

     使用Proxy.newProxyInstance()建立代理对象=>

     调用InvocationHandler的invoke()方法传入被代理对象的方法名称和运行变量,将实际运行的对象交给method.invoke()

      =>method.invoke()返回的对象是实际方法运行后的回传结果

     12.Ant构建工具,Junit测试工具