Java基础学习笔记
最近在学习大数据,然后就学习了一下java基础,下边是基础笔记:
java学习笔记:
<chp1>
1>java + 类名:执行时不要带".class",否则报错。
2>javac编译".java"文件时,文件中的类会被分别编译成对应的"类名.class"
3>类或接口为public时,必须与文件名一样,包括大小写。一个文件只能有一个公开类或接口。
<chp2>
1>注释:注意是javadoc的注释方式:/** */
2>package包:(必须在文件开始声明)
①便于对class文件管理,但注意必须与文件目录一直才行,否知执行报错
②包可以防止类名冲突。
③命名原则:与网址相反,abc.com 对应 com.abc.corejava
3>import包:
①当package出现,package存在文件的开始位置,import排在其后。
②import 可以导入某包内的一级类,如 "import java.util.*",但注意不会导入其下的子包中的类。
③默认情况下,已经导入"import java.lang.*",不需要自行导入。
4>java是区分大小写的
5>命名规范:包、类、方法、变量、常量
①包名:全小写
②类名:大骆峰
③变量/函数名:小骆峰
④常量:全大写,单词间下划线隔开。HELLO_WORLD
6>数据类型:
①8中基本数据类型
②String类:"+"可以拼接字符串与任何类型,结果都是字符串。
③局部变量:必须先复制后使用,否则编译报错。作用域是从声明开始到该级别代码块结束,包括子代码块中。
<chp3>
①Scanner
<chp5>
1>数组:
①隐式初始化时,不能指定数据大小,JVM根据实际参数格式分配
②二维数组中支持不规则数组
<chp6>对象和类
1>成员属性:可以在代码中直接初始化(与C++不同),并且不会与方法中的变量冲突。
2>成员方法:
①重载:方法名相同,参数列表不同。
②构造函数:和C++一样,可以重载构造函数,有默认的无参构造函数。
3>对象创建过程:
①根据类属性大小,分配内存,设置默认值:bool的为false,int的为0
②根据代码,初始化成员变量。
③调用构造函数。
④引用:与C++一样作用,只是方式不太一样,引用传递
④this:this()只能在构造函数使用,表示调用本类的其他构造函数,完成对象的构造
只能用在构造函数的第一句,否则报错。
注意不能在构造函数中通过this()调用自己,这样递归是有问题的。
<chp7>面向对象的三大特性
1>封装:
①问修饰符:
private:类内部
public:都可以通过对象访问
default:类内部,同包范围内,当继承的父类是在其他包中时,子类是无法访问defalut的成员变量的。
protected:类内部,同包内部,不同包的子类中。
2>继承:
①extends:
②覆盖:方法覆盖对方法的5部分都有要求,访问修饰符、返回值、函数名、参数列表、异常
③对象创建过程:
->分配空间,赋默认值
->由根至子,依次初始化
->由根至子,依次调用构造函数
调用父类构造函数的时候,默认的调用无参构造函数,
如果需要调用指定的构造函数,使用super(参数列表)调用
注意:在使用super时,必须作为构造函数的第一句。
以为值this和super在构造函数中不能共存。
构造函数的第一句,有三种互斥情况:
①super(参数)
②this(参数)
③前两者都不是,编译器自动加上super(),即调用父类的无参构造函数。
->super是指向父类的引用,this是指向子类的引用。
->java是单继承,与C++多继承不同。
3>多态:父类引用引用子类对象,只能调用父类定义的方法,但方法可能被子类重写,此时调用的就是被重写的方法。
①instanceof: 对象的引用 instanceof 类,返回值为bool类型。
②多态的N种方式:
->父类引用 指向子类对象,可能是多层继承关系
->接口引用 指向实现类的对象,多继承关系多层继承关系;
->方法多态:重载和覆盖(可以super调用父类被覆盖的方法,从而实现对父类方法的扩充)
<chp8>三个修饰符:static、final、abstract
1>修饰的对象:
①static:属性,方法,初始化代码块;注意其不能修饰局部变量和类。
②final:变量(包括属性和局部变量(方法参数也是局部变量)),方法,类
③abstract:类,方法
2>含义
①static:
->属性:静态成员变量,类变量,是所有对象共有的。相反,非静态属性,是实例变量
->方法:非静态方法,无论属性和方法是否静态,都能访问。
静态方法,只能访问静态属性和方法.
->初始化代码块:初始化代码块,就是在类中,方法外的,{}内的代码块
静态代码块,在类加载的时候只执行一次;
非静态代码块,在类加载的时候执行多次。
②final:类似const
->局部变量:一次赋值机会,以后只读;
->属性:对象创建完成之前有一次赋值机会,即初始化属性或者构造函数中;
属性没有默认值,所以必须在建立对象之前,完成对属性的赋值,否则编译器报错;
如果未初始化属性,则所有构造函数都需要实现对其的赋值,注意此时构造函数是不能相互调用的;
注意:因为静态属性是在类加载的时候分配空间的,因此static final 属性只能初始化赋值;
->方法:修饰方法表示子类无法重写父类的该方法;
->类:表示该类不能被继承;
③abstract:类似C++ virtual
->类:表示是抽象类,不能实例化,但可以申明引用,指向子类对象。即C++中含有纯虚函数的类为抽象类
->方法:表示方法只是声明,没有实现,需要子类实现,该类无法创建对象;
抽象方法必须是在抽象类中,但抽象类不一定含有抽象方法;与C++不太相同
子类继承抽象类,要么成为抽象类,要么必须实现全部抽象类的抽象方法;
<chp9>接口
1>接口:特殊的抽象类,即:
所有属性都是public static final修饰
所有方法都是public abstract 修饰
2>声明方法:interface 接口名
3>注意:
->interface 与符合要求的abstract class类似,但声明时可以省略访问修饰符;
即:属性 省略public static final
方法 省略public abstract
->类实现接口,使用关键词:implements
->一个类实现接口,如果不希望其为抽象类,则必须实现全部方法;
->因为接口方法是public的,所以实现类中的实现方法必须使用public修饰;
->接口之间也存在继承,使用关键词extends;
->接口继承可以是多继承的;
->类是单继承,接口可以多继承,且子类继承父类,实现接口时,继承在前,实现在后,否则编译出错;
4>关于java类的单继承,接口的多继承 与 C++类多继承的思考:
①java类继承时主要类型,接口是次要类型;
②基类是事物主要共性的抽象,接口是次要共性的抽象;
③单继承,父子类之间是简单的树形结构,及时是接口的多继承也不会破坏这个树形关系;
④接口解耦合,其实就是多态。接口就是方法的抽象的集合,是需要实现的标准;
当接口的实现这变化的时候,对接口的使用者不产生影响;
与代理模式极其相似,声明代理,就是声明接口,实现代理就是实现接口,从而降低使用者和实现者的耦合关系;
对于项目开发而言,可以实现多个模块或者系统的并行开发工作,提高开发效率;
⑤接口回调:实际就是系统库中,定义接口,调用调用者的实现,从而实现接口的回调。
与C++ stl模板库中算法中排序,也是这种思想;
⑥泛型:接口调用时,很多是工具类封装的接口,程序实现接口,但是为了工具类的扩张性,
以Comparable接口为例,接口定义的是泛型型的,实现是需要类型化
与C++的模板库中的模板思想是一致的;
<chp10>Object物种起源
1>finalize:JVM垃圾回收时调用,SUM的垃圾回收是内存不足是回收垃圾
所以,释放资源,最好调用System.gc()方法,但也不是马上释放资源,只是通知垃圾回收机制需要释放资源了。
2>getClass:与instanceof类似,不同在于前者可以精确判断引用的真是类型,后者只能判断引用是否是某个类的实例,不能精确判断是那个类的实例,因为后者在判断是父类的实例时也返回true
3>equals:注意与"=="的区别,前者是比较引用对象的值是否相等,后者是比较引用对象的地址是否相等;
自定义类时,如果用到equals方法,则需要覆盖父类的equals方法:
覆盖equals的五个步骤:
①判断 this == obj
②判断 obj == null
③判断两个对象的实际类型(getClass)
④强制类型转换
⑤判断两个对象的属性是否都相等
4>toString:类似OC的description;
5>封装类:Object类型的引用可以指向任意类型的对象,但是在指向基本数据类型的时候力不从心,
所以,Sun封装了八大包装类,实现Object类对八大基本基本数据类型的引用;
6>数据类型转换:①字符串,②包装类,③基本数据类型
①<->②:前者直接调用包装类的构造方法;后者调用toString方法
①<->③:前者是对应调用Integer.parseInt(str);后者调用:""+数据 或者调用静态方法String.valuesOf(数据);
②<->③:前者调用构函数;后者类似intValues()方法即可;
7>自动封箱和拆箱:JDK5后新增特性,可以隐式实现包装类和基本数据类型的装换,其实是编译器处理过,底层实现还是一样的
如:int i = myInteger; myInt++;
目的是更加方便的操作基本数据类型和包装类。
8>四种内部类:和C++的内部类基本类似,实用性不强,暂时不看
<11>集合框架:类似C++ STL
1>系统接口
①Collection:数据是object类型
->List:有序
->Set:无序,唯一
->SortedSet:有序,唯一
②Map:数据是键值对类型
->Map:键不能重复
->SortedMap:键对象按照排序规则,自动排序
2>详细方法介绍:
①Collection接口:
->add
->contains
->isEmpty
->iterator 迭代器
->remove
->clear
->size
②List接口:
->add(Object),add(index,Object) :前者是继承,后者是新增
->get(index),set(index,element):前者是获得
->indexof(Object):查找对象
->实现List接口的的类:注意泛型,就是模板思想
①ArrayList:底层实现线性表,查找快,增删慢
②LinkedList:底层实现是链表,增删快,查找慢
③Vector:底层实现线性表,与ArrayList类似,但线程安全
③Set接口:
->add(Object)
->实现Set接口的类:
①HashSet:自定义类时,需要重写覆盖父类的equals和hashCode方法,否则无法满足Set特性;
因为HashSet的特性是,首先判断其hashCode的值是否相同,如果相同,再调用equals判断;
如果不重写equals和hashCode方法,则会调用父类的该方法;
->SortedSet接口:元素不重复,并且经过排序
->实现SortedSet接口的类:TreeSet,该类中存放的对象都必须实现Comparable接口;
②Map接口:
->Object get(Object key)
->put(Object key,Object value);如果键值不存在则插入,如果存在则更新其值
->remove(Object key)
->Set keySet();获得key的集合
->Collection values();获得所有值value的集合,因为可能重复,不能是Set.
->containsKey/containsValue
->size;键的个数
->isEmpty;
->clear
->entaySet
->Map的实现类:
①HashMap:键值对中的key必须重写equals,hashCode方法,线程不安全,null可以作为键/值;
②LinkedHashMap:可以保证放入键值的顺序
③HashTable:线程安全,null作为键/值时抛出异常
->Map.Entry是Map的内部接口
->SortedMap子接口:有序
->实现类是TreeMap:意味着放入的对象必须实了Comparable接口;
3>foreach遍历集合:
for(Object obj : set){
System.out.println(obj);
}
4>泛型:就是C++模板思想,泛型不能多态;
<shp12>异常处理:程序的白衣天使
1>异常分类:
Throwable类:所有错误的父类
|-Error:严重底层错误,无法处理
|-Exception:异常,异常处理的主要对象
|-RuntimeException:未检查异常,可以避免,可选择处理,编译可以通过。
|-非RuntimeException:无法避免的异常,必须处理,否则编译不通过
2>抛出异常后,异常对象会沿着方法调用链反向传递。当异常都没有处理,抛给你了虚拟机,则虚拟机只能停止当前程序。
3>捕获异常:try{可能不是全部代码都执行} catch(){异常处理} finally{一定执行的代码,主要是释放资源,事务处理}
<shp13>多线程 2种方式:
1>继承Thread类,注意Thread类不是抽象类,重写run()方法,使用start启动线程!
2>实现Runnable接口,实现run()方法,使用run启动线程
3>线程状态。阻塞:sleep(),join()
4>同步和互斥。
①synchronized(lock){}同步代码块与synchronized访问修饰符,实现互斥资源的互斥访问
②wait,signalAll();实现同步;
<shp14>I/O框架
1>File类:表示文件和文件夹
2>字节流:
1> 抽象类 其子类 构造函数 其他
InputStream: FileInputStream String filename;File file; close;read
OutputStream: FileOutputStream String filename;File file; close;write
2>字节过滤流:
->增强读写八种基本数据类型和String
DataInputStream: readInt等
DataOutputStream: writeInt等
使用步骤:①创建节点流,②封装过滤流,③读写数据,④关闭外层流(内存流自动关闭)
->提高I/O的读写效率:注意①缓冲区满 ②调用close ③flush方法 会清空缓冲区,完成读写
BufferedOutputStream:
BufferedIntputStream:
->增强基本数据类型,String,缓冲区功能,对象的读写,对象序列化:
ObjectInputStream: readObject();
ObjectOutputStream: writeOject();
注意:实现了java.io.Serializable接口的对象才能序列化。当属性被transient修饰时,才不参与序列化。
4>字符流:
1> 抽象类 其子类 桥转换(字节流转为字符流)
Reader: FileReader, InputStreamReader
Writer: FileWriter, OutputStreamWriter
2>字符过滤流: 方法
->BufferReader: String readLine()
->PrintWriter:
<chp15>网络编程
1>TCP :ServerSocket Socket getInputStream 桥转换和过滤流,使用BufferedReader和PrintWriter进行IO操作
1>TCP服务器端:
①创建ServerSocket对象,绑定端口
②调用accept,等待请求
③调用getXXXStream,io
④关闭socket
2>TCP客户端:
①创建socket对象,连接服务器
②调用getXXXStream方法,IO
③关闭Socket;
2>UDP:DatagramSocket DatagramPacket进行IO的操作
1>UDP服务器:
2>UDP客户端:
3>URL:
URL url = new URL("http://www.sina.com.cn");
URLConnection conn = url.openConnection();
InputStream in = conn.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
<shp16反射>
1>class:泛型,Class<?>
1>类对象获取方式:
①类名.class;
②对象.getClass();
③Class.forName();
2>类名和接口名的获取:
①getName();
②getSimpleName();
③getSuperclass().getName()
④getInterfaces();
2>方法:Method
1>获取方法:
①getMethods:获取所有的该类和从父类继承的非private修饰的方法数组
②getDeclaredMethods:获取该类中申明的所有方法的数组,不包括从父类中继承的。
③getMethod(方法名,参数类对象数组):因为存在重载,所以需要参数类对象数组,方法的范围同上描述
③getDeclaredMethod(方法名,参数类对象数组):因为存在重载,所以需要参数类对象数组,方法的范围同上描述
2>获取方法名:
①getName:获取方法名,不包括包名
②toString:获取方法的签名
2>使用方法:
invoke(对象,参数列表Object数组):方法、对象、参数值
3>属性:Field
1>获取属性:
①getField(String):获取类的对象及从父类继承的非private属性
②getDeclaredField(String):获取类的对象所有属性,不包括继承的;
2>操作属性:
①Get:直接获得即可
②Set:对于私有属性,使用之前设置setAccessible(true),才能对其属性赋值;
4>构造函数:Constructor
1>获取构造函数:
Constructor con = c.getConstructor(new Class[]{String.class,int.class});
2>使用构造函数:
①con.newInstance(new Object[]{"Cz",new Integer(28)});
②c.newInstance();//无参构造函数
5>应用;
String className = "Student";
Class<?> c = Class.forName(className);
Object o = c.newInstance();
//注意className,必须是完整的类名,包括包名;
String methodName = "study";
Method m = c.getDeclaredMethod(methodName,new Class[]{});
m.invoke(o,new Object[]{});
将类名和方法字符串化,实现代码的复用,多态的体现。和OC中通过方法名或者属性名操作对象类似。
反射是底层操作,虽与封装思想相违背,但它是底层的操作,可以提高代码重用,多用于工具和框架;
反射不足:效率较低,比较复杂,不易调试;
<chp17>OOAD:面向对象的分析与设计
1>设计模式:
①单例:
public class Singleton{
private Singleton (){}
private static Singleton instance = new Singleton();
public static Singleton getInstance(){
return instance;
}
}
②简单工厂模式
2>数据分3层:通过反射机制,实现修改配置文件,即可修改系统的三层中的处理方式。
①DAO:
②BO(biz):
③VO:
最后一个简单的三层代码:
接口部分:
1 package dao; 2 3 public interface Dao{ 4 String getData(); 5 }
1 package biz; 2 import dao.Dao; 3 4 public interface Biz{ 5 void setDao(Dao dao); 6 String dealData(); 7 }
1 package view; 2 import biz.Biz; 3 4 public interface View{ 5 void setBiz(Biz biz); 6 void showData(); 7 }
实现类:
1 package dao; 2 //放在同一个报下 3 //import dao.Dao; 4 import java.io.*; 5 6 7 public class FileDaoImpl implements Dao{ 8 public String getData(){ 9 String data = ""; 10 BufferedReader br = null; 11 String tmp = ""; 12 try { 13 br = new BufferedReader(new FileReader("test.txt")); 14 while((tmp = br.readLine()) != null) 15 { 16 //System.out.println(tmp); 17 //System.out.println(data); 18 data += tmp; 19 data += '\n'; 20 } 21 } catch (IOException e) { 22 e.printStackTrace(); 23 }finally { 24 if(br != null){ 25 try { 26 br.close(); 27 } catch (IOException e) { 28 e.printStackTrace(); 29 } 30 } 31 } 32 33 return data; 34 } 35 }
1 package dao; 2 //放在同一个报下 3 //import dao.Dao; 4 import java.io.*; 5 import java.net.*; 6 7 8 public class NetDaoImpl implements Dao{ 9 public String getData() { 10 String data = null,tmp = null; 11 URL url = null; 12 URLConnection conn =null; 13 InputStream in = null; 14 BufferedReader br = null; 15 16 try { 17 url = new URL("http://www.sina.com.cn"); 18 conn = url.openConnection(); 19 in = conn.getInputStream(); 20 br = new BufferedReader(new InputStreamReader(in)); 21 String line = null; 22 23 while((tmp = br.readLine()) != null){ 24 data += tmp; 25 } 26 } catch (Exception e) { 27 e.printStackTrace(); 28 } 29 finally { 30 try { 31 if(br != null){ 32 br.close(); 33 } 34 } catch (Exception e) { 35 e.printStackTrace(); 36 } 37 38 return data; 39 } 40 41 42 43 } 44 }
1 package biz; 2 import dao.Dao; 3 4 public class UpperCaseBizImpl implements Biz{ 5 private Dao dao; 6 7 public String dealData(){ 8 String data = dao.getData(); 9 if (data != null) { 10 data = data.toUpperCase(); 11 } 12 return data; 13 } 14 public void setDao(Dao dao){ 15 this.dao = dao; 16 } 17 }
1 package biz; 2 import dao.Dao; 3 4 public class LowerCaseBizImpl implements Biz{ 5 private Dao dao; 6 7 public String dealData(){ 8 String data = dao.getData(); 9 if (data != null) { 10 data = data.toLowerCase(); 11 } 12 return data; 13 } 14 public void setDao(Dao dao){ 15 this.dao = dao; 16 } 17 }
1 package view; 2 import biz.Biz; 3 4 public class TextView implements View{ 5 private Biz biz; 6 7 public void setBiz(Biz biz){ 8 this.biz = biz; 9 } 10 public void showData(){ 11 System.out.println( biz.dealData()); 12 } 13 }
工厂类:
1 package simplefactory; 2 import dao.*; 3 import biz.*; 4 import view.*; 5 import java.util.Properties; 6 import java.io.*; 7 8 //单例模式 9 public class SimpleFactory{ 10 { 11 props = new Properties(); 12 InputStream is = null; 13 try { 14 is = new FileInputStream("conf.props"); 15 props.load(is); 16 } catch (IOException e) { 17 e.printStackTrace(); 18 } 19 finally { 20 if(is != null){ 21 try { 22 is.close(); 23 } catch (Exception e) { 24 e.printStackTrace(); 25 } 26 } 27 } 28 } 29 private static Properties props; 30 private SimpleFactory (){} 31 private static SimpleFactory instance = new SimpleFactory(); 32 public static SimpleFactory getInstance(){ 33 return instance; 34 } 35 public static Object createObject(String name){ 36 Object obj = null; 37 String objName = props.getProperty(name); 38 try { 39 Class c = Class.forName(objName); 40 obj = c.newInstance(); 41 } catch (Exception e) { 42 e.printStackTrace(); 43 } 44 return obj; 45 } 46 } 47 48 /* 49 public class SimpleFactory{ 50 private Properties props; 51 52 public SimpleFactory(){ 53 props = new Properties(); 54 InputStream is = null; 55 try { 56 is = new FileInputStream("conf.props"); 57 props.load(is); 58 } catch (IOException e) { 59 e.printStackTrace(); 60 } 61 finally { 62 if(is != null){ 63 try { 64 is.close(); 65 } catch (Exception e) { 66 e.printStackTrace(); 67 } 68 } 69 } 70 } 71 public static Dao createDao(){ 72 return new FileDaoImpl(); 73 } 74 public static Biz createBiz(){ 75 //return new UpperCaseBizImpl(); 76 return new LowerCaseBizImpl(); 77 } 78 public static View createView(){ 79 return new TextView(); 80 } 81 public Object createObject(String name){ 82 Object obj = null; 83 String objName = props.getProperty(name); 84 try { 85 Class c = Class.forName(objName); 86 obj = c.newInstance(); 87 } catch (Exception e) { 88 e.printStackTrace(); 89 } 90 return obj; 91 } 92 } 93 */
测试类:
1 package test; 2 import dao.*; 3 import biz.*; 4 import view.*; 5 import simplefactory.SimpleFactory; 6 7 public class TestMain { 8 public static void main(String [] args){ 9 Dao dao = (Dao)SimpleFactory.createObject("dao"); 10 Biz biz = (Biz)SimpleFactory.createObject("biz"); 11 biz.setDao(dao); 12 //View view = (View)SimpleFactory.createObject("view.TextView"); 13 View view = (View)SimpleFactory.createObject("view"); 14 view.setBiz(biz); 15 16 view.showData(); 17 } 18 }
编译的时候,我使用的dos命令javac命令,注意加"-d .",编译器自动在当前目录下创建包名对应的文件夹,并将类文件放入其中。
配置文件:
dao=dao.NetDaoImpl biz=biz.LowerCaseBizImpl view=view.TextView