可重用性可拓展性可维护性
1
Javac java
源代码.java字节码 .class JVM 操作系统
数据类型:节省内存空间
基本数据类型、引用数据类型(各种类(作用:封装数据)、数组、接口)
定义=声明+初始化
int age;
age = 18;
数据类型变量名=值、同类型的变量名
int age = 18;
age1 = age;
方法中的局部变量没有默认值!其他有。
布尔类型、字符类型、整数类型、浮点类型。
数字类型的变量默认值为0(0, 0.0f, 0.0D) char :\u0000 boolean : false 引用数据类型 null
局部变量:1 2方法体内 3 形式参数
自动(隐式)类型转换小到大向上转换还有字符型转整数型
强制(显式)类型转换大到小向下转换整数型转字符型前加“(char)”
操作符
+ - * / age += 1! age = age +1 %= (除以一个数取余数)
age ++ ++ age操作符在前 先加后用(先打印 后加上去)
如果单个运算组成一个语句时++在前在后一样
switch语句中的表达式只能是byte,short,char,int以及枚举(enum),所以当表达式是byte的时候可以隐含转换为int类型,而long字节比int字节多,不能隐式转化为int类型,所以switch语句可以用在byte上而不可以用在long上,另外由于在JDK7.0中引入了新特性,所以witch语句可以接收一个String类型的值,String可以作用在switch语句上
2
(语句?成立 :不成立)条件运算符 相当于if else
nums.length遍历的时候在for循环内外的性能优化
程序控制语句:if switch while与do..while for break continue return
//foreach本质还是for循环,只是在写法上简单了 语法糖:suger syntax,
int[] nums = {2, 4, 5, 8};
for(int num : nums){System.out.println}
重载看的是方法签名=方法名+参数列表(参数个数、类型、顺序(与标识符无关))
重写看方法签名和返回类型必须相同子类方法不能缩小父类的访问权限存在于不同类
重写:子类的方法和父类的方法签名完全一致。重写重载与返回值无关
抽方法的时候没有的变量全是参数
类和对象:
定义类:定义成员变量、成员方法。实例化对象、初始化对象
Dog dog = new Dog();
new:在堆内开辟一个内存空间 用来装当前new的对象 Dog() 初始化 创建对象
dog = new Dog();把对象在内存中的地址码赋给变量dog。
Dog(){}:调用Dog类的构造方法 ///main()方法/////成员方法
Heap堆和Stack栈
堆:类的对象从中分配内存空间,new,堆的优势是动态的分配内存大小,所以存取速度慢
栈:存取速度快,栈数据可共享,栈主要存基本数据类型和对象句柄
例:String str1 =“abc”; String str2 = “abc”;这是在栈中创建 str1创建的abc共享与str2。
String str1 = new String(“abc”); String str2 = new String(“abc”);堆中创建,每次生成新对象
栈操作:push() pop();
==和equals
前者是比较引用是否指向同一个对象后者比较类里的数值是否相等
每一个类中都默认有一个无参构造方法如果自己定义无参构造方法就没有默认的了
构造方法:初始化构造器:没有返回值并且方法名与类名相同的方法就是该类的初始化构造器。用来初始化当前对象(给当前对象的字段赋值)。
自定义构造方法妙用:(既创建对象,又能立即完成对象的初始化)
类成员变量使用static类名.方法名
实例成员变量无static创建对象(new) 然后用 对象.方法名
多参数:本质就是一个数组int[] sum int... sum
Call by Value就是传值的方式,函数调用时是把实参的值传给形参,函数调用结束后形参的值不能带回给实参。Call by Reference就是传地址的方式,函数调用时是把实参的地值传给形参,也就是说实参和形参共用同一个存储空间,函数调用结束后,形参的值自然“带回”给实参了。
导入:导入包(需要使用的类的权限定名)当工作包和需要包不同包时,需要导入
java.lang包下的类会被自动导入,但子包还是需要导
静态导入:直接使用一些类的成员,不需要类名.调用的时候使用静态导入 对象:使用static修饰的成员
修饰符:访问修饰符(public .................) 和其他(static final)
static可通过 “类.成员变量” 调用 没有static 就new调用
一般不放在类前
方法前、字段前表明该方法或字段属于类不属于对象可以被类名.xx调用
Static可放在内部类之前 表示内部类属于外部类的成员
什么时候使用:1状态、行为属于整个事物、类 2 被所有对象所共享 3在开发中往往把工具方法使用static修饰
Final: 类前 不能被继承 方法前 不能被重写 最终方法 字段前 常量
3
封装:隐藏实现细节通过公共方法向外暴露该对象的功能作用:解耦
封装:解耦隐藏对象的实现细节通过公共方法来向外暴露该对象的功能
方法的封装就是把数据和逻辑分离的过程设计方法的封装取决于1返回值2 形参
继承:类与类之间的关系包含关系
继承:把一堆事物的共同属性提取出来形成类,再把类中的共有属性提取出来形成父类。
上转型对象:把子类创建的对象b的引用放到父类的对象a中,称a是b的上转型对象
多态:当调用某个类的时候,如果当前对象有这个方法,那么就直接调用这个方法,否则,去当前类的父类对应的对象中找这个方法,如果有直接调用,如果没有继续找父类,找到调用,找不到报错。
对象的上转型对象:子类的对象的引用放到父类的对象中时,称父类的对象是子类对象的上转型对象
①上转型对象不能操作子类新增的成员变量和方法
②可以操作子类继承或重写的成员变量和方法
③若子类重写了父类的某个方法,当对象的上转型对象调用这个方法时调用的是重写的方法
多态:用父类的变量接收子类的对象,运行时表现子类的行为
类的字段不能表现出多态性。
内存空间:堆栈方法区(加载字节码文件.class) 常量区
4
过程大事化小对象分门别类
字段加set方法get方法 = 属性
-this当前类对应的对象! 当局部变量和类的成员变量同名时,该局部变量作用区域内的成员变量就被隐藏了,必须用this来指明。 (将形参的值赋给成员变量。)
-super操作父类对应的对象! 调用父类的构造方法必须放在当前构造方法的首行
子类的构造方法默认情况下会调用父类的无参构造方法/子类不能继承父类的构造方法,因此要用super(xx, xx) ;(子类的无参构造方法中默认有super())
子类的成员变量和方法和父类的同名时:
super调用父类被隐藏的成员变量和方法 super.xxx
Instanceof:运算符判断某个对象是某一个类或他的子类
():调用
return返回的一定是一个对象
局部代码块:直接定义在方法内部的代码块。
初始化代码块(构造代码块):编译时进入无参构造方法中直接定义在类中
静态随类直接加载进内存
静态代码块:使用static修饰的初始化代码块 在主方法执行之前执行一次。
在编译过程中,字段的直接初始化和初始化代码块被放在了这个类中的无参构造方法中,从上至下依次放入无参构造方法。
5
StringBuffer类
表示一个本身内容可变的字符串对象,用于完成字符串的动态添加、插入、替换等操作。
append() insert()
包装类:
Integer引用数据类型
Human human = new Human(); human.age = new Integer(18);/ human.age = 18;
自动装箱/自动拆箱:对象是数据 不是类型
拆箱:把对象转换成一个基本数据类型基本数据类型变量名=对象.xxxValue; 自动转
装箱:把一个基本数据类型的数据转换成引用数据类型的数据(对象)
引用数据类型对象名= XXX.valueOf(5);
Object... object多参数
如果把object变为string 一下三种方法相当于是把String转化为包装类。
Object o = 18;/
Objecet o= Integer.valueOf(18);上下一样 编译器自动上转下
Object o = new Integer(18);以上三种形式
把包装类转换为String
//String到包装类
String str = "12";
Integer a = Integer.valueOf(str);
//包装类到String
String s2 = a.toString();
‘基本数据类型到String’String到基本数据类型
int i = 8;
String temp = String.valueOf(i);
String s = "18";
int j = Integer.parseInt(s);
类操作:getClass() getName() getSuperclass()
打印就是调用该对象的toString()方法
String s = “abc”;直接赋一个字面量 在常量区
String s1 = new String(“abc”);通过构造器创建 在堆中new
int age = 18;直接存在栈中
null和””空的不同。
没分配内存有空间没值
方法中的变量为局部变量必须初始化啊
==比较的是两个对象的首地址(内存地址)
编译常量池运行常量池
7
Random随机[0-1)的数
ThreadLocalRandom随机一个区间的数
UUID获取时空中绝不重复的随机数(非数字)
带种子不带种子
Date日期 直接new 系统当前时间
getTime()获取date毫秒
System.currentTimeMillis()返回毫秒
SimpleDateFormat("yyyy.MM.dd HH*mm*ss")文本转换成Date
.format(date)Date转换到文本
DateFormat.getDateInstance().format() 获取短时间
.get(Calendar.获取日历中的元素Calendar抽象类
s.matches(regex)正则表达式(Regex)比较
Math.ceil Math.floor
9
java集合框架
接口Collection无序集合{① List 有序 可重复
②Set 无序 不重复 不存在get方法 Hashset
①ArraysList (数组结构)查询快 增删慢 长度可变
②LinkedList (链表) 增删速度快 查询慢
1. Vector & ArrayList 1) Vector的方法都是同步的(Synchronized),是线程安全的(thread-safe),而ArrayList的方法不是,由于线程的同步必然要影响性能,因此,ArrayList的性能比Vector好。 2) 当Vector或ArrayList中的元素超过它的初始大小时,Vector会将它的容量翻倍,而ArrayList只增加50%的大小,这样,ArrayList就有利于节约内存空间。
3)源码,区别在于可以设置capacityIncrement容量长度,而ArrayList只能设置initialCapacity默认长度
public Vector(int initialCapacity, int capacityIncrement){
2. Hashtable & HashMap Hashtable和HashMap它们的性能方面的比较类似 Vector和ArrayList,比如Hashtable的方法是同步的,而HashMap的不是。
3. ArrayList & LinkedList
ArrayList的内部实现是基于内部数组Object[],所以从概念上讲,它更象数组,但LinkedList的内部实现是基于一组连接的记录,所以,它更象一个链表结构,所以,它们在性能上有很大的差别: 从上面的分析可知,在ArrayList的前面或中间插入数据时,你必须将其后的所有数据相应的后移,这样必然要花费较多时间,所以,当你的操作是在一列数据的后面添加数据而不是在前面或中间,并且需要随机地访问其中的元素时,使用ArrayList会提供比较好的性能; 而访问链表中的某个元素时,就必须从链表的一端开始沿着连接方向一个一个元素地去查找,直到找到所需的元素为止,所以,当你的操作是在一列数据的前面或中间添加或删除数据,并且按照顺序访问其中的元素时,就应该使用LinkedList了。
如果在编程中,1、2两种情形交替出现,这时,你可以考虑使用List这样的通用接口,而不用关心具体的实现,在具体的情形下,它的性能由具体的实现来保证。
4.配置集合类的初始大小 在Java集合框架中的大部分类的大小是可以随着元素个数的增加而相应的增加的,我们似乎不用关心它的初始大小,但如果我们考虑类的性能问题时,就一定要考虑尽可能地设置好集合对象的初始大小,这将大大提高代码的性能。 比如,Hashtable缺省的初始大小为101,载入因子为0.75,即如果其中的元素个数超过75个,它就必须增加大小并重新组织元素,所以,如果你知道在创建一个新的Hashtable对象时就知道元素的确切数目如为110,那么,就应将其初始大小设为110/0.75=148,这样,就可以避免重新组织内存并增加大小。
集合的迭代操作(遍历)
next()的每次调用都会移动指针 hasnext()只会判断有没有下一个
Iterator只能从前向后遍历 ListIterator可以双向遍历
注意开始的时候指针在第一个位置的时候不能向左遍历
迭代器:基本数据类型foreach循环的编译结果是普通的,引用数据类型是使用了迭代器
iterator.remove()迭代器删除 括号中不需要传入移除的对象 当前遍历的对象就是移除对象
迭代器可以一边遍历一边删除
泛型:泛型类、泛型方法在集合框架中使用较多,约束集合中元素的类型
<>前后必须一致 带<>的都是声明,并非返回值类型 语法糖 底层是强转
Map接口 Map(k,v) 通过 key查找 value 遍历:迭代器或foreach
10
Collections算法类
工具类大多由s结尾,如Collections
抽象类:使用abstract修饰的类
抽象方法:没有方法体并且使用abstract修饰符修饰的方法。 必须放在抽象类中。
抽象类不一定包含抽象方法。
只有方法的定义和方法的实现交给继承他的子类去完成。
继承自抽象类的子类,必须实现抽象类中的所有!抽象方法。
优点:易于扩充新的类。抽象方法必须定义在抽象类或接口中。
有抽象方法必是抽象类,抽象类中的方法不一定是抽象方法
使用abstract修饰的类,不能创建实例即new;
普通类有的成员(方法字段构造器)抽象类也有;
接口:
修饰符只能是默认的或public
interface implements
实现类的方法的访问权限必须大于等于接口的方法声明的访问权限
接口里的方法都是抽象方法字段(数据)是全局静态常量即具有public static final属性(一般不写)
如果实现接口的类不是抽象类,他必须实现接口的所有方法。
被实现的接口可以有多个。(与类的继承的不同)
接口之间也可以有继承关系,子接口拥有父接口的方法,自己还可以定义方法
接口也可实现多态
抽象类和接口的比较:①抽象类是单继承,接口是多实现。②抽象类有非抽象方法,接口全是抽象方法。③抽象类的方法的修饰符4中都有,接口的方法都是public。④抽象类有构造方法。
相同:都不能实例化,都可以实现多态
Object类
public boolean equals(Object obj)比较hashCode 两个new对象是不相等(实际上是指向同一个对象时方等价)
内部类:
定义在类结构中的类
①增强封装:把内部类隐藏在外部类中,不允许其他类访问。
②内部类能直接访问外部类的成员
[if !supportLists]1、[endif]实例内部类内部类没有static修饰 ()
2、静态内部类 使用static (内部类的方法可以直接调用外部类的静态成员)
3、局部内部类 在方法中定义的内部类 (想要执行局部内部类中的方法 必须创建局部内部类的实例)
4、匿名内部类 没有类名的内部类 属于局部内部类的特殊
set()方法 修改属性变量的值
get()方法 获得属性变量的值
枚举:一个特殊的类固定多个常量对象的集合(定义常量时)成员都是全局静态常量
[修饰符]enum 枚举类名
{常量A,常量B;
}
6
设计模式
单例设计模式在程序运行过程中,只存在一份内存
//私有化构造方法,让本类不能在外界new,创建新的对象。//饿汉模式 懒汉模式
方法模板设计模式:多态的应用
8
异常处理try - catch - finally - throws - throw
throw抛异常
throws声明可能抛异常
①编译型异常 如果自己不处理的情况下 在所在的方法声明之后必须加上throws 以表示次方法可能会报异常
②运行时异常 在所在的方法声明之后加不加throws都可以
try-catch是用来处理所调用方法中throw出来的异常的
对于编译型的异常,如果这个异常我们使用try-catch处理过了,就不用throws声明抛出了
中断异常不时出现中断就会出现异常,
try-catch新特性:
11
多线程
并行多核 并发单核
进程:执行的程序线程:单个进程内部可在同一时刻进行多种运算、有多个执行点
区别:同一个线程类创建的多个线程共享一块内存空间和系统资源,每个线程的数据保存在寄存器和一个系统栈中。
用Thread来创建进程 实现Runnable接口来创建进程:共享数据
线程不光要创建,创建完成后必须启动
才能开启该条线程
new创建的线程都是子线程
写在成员变量里要考虑线程安全
Runtime.getRuntime()与ProcessBuilder。
可以打开某些程序
等待this.wait();需要 唤醒 this.notify();
sleep不需要唤醒
使用synchronized修饰的方法就是同步方法(互斥方法) 作用:保证该修饰方法同时只能够被一个线程访问
Lock
.join();中途加入一个线程(先跑)。
stop()不安全 suspend() 易死锁
12
I/O处理
所以我们把从外部设备流向程序的流成为输入流
反之,把从程序流向外部设备的流称为输出流.
InputStream:实现了从输入流读取数据的功能
OutputStream:实现了从程序向输出流写数据的功能
抽象类:字节流InputStream/OutputStream一般传输二进制数据一次读一个字节
字符流Reader/Writer 一般传输文本数据 一次读一个字符
流都是抽象类无法new,所以通过实例化他的子类来实现(实例化抽象类子类的时候会实现抽象类的所有构造方 法)
Write.flush()强制将缓存中的内存写入文件
关闭流input.close()会自动调用flush()方法
InputStream的read()方法返回-1后,说明到达文件尾,不能再读取。
1、包装流
①转换流
InputStreamReader OutputStreamWriter
只需要关闭包装流一个,不需要关闭被包装流。
②缓冲流
BufferedInputStream BufferedOutputStream BufferedReader BufferedWriter
③合并流/顺序流/序列流
SequenceInputStream
将两个流合并。
2、对象流(序列化:编码的过程/ 反序列化:解码的过程)
①序列化:ObjectOutputStream
②反序列化:ObjectInputStream
ObjectOutputStream
3、标准I/O
4、DataOutputStream 可写字符串
File文件
new File()没有无参构造器
读一个文件夹里的文件
如果还含有文件夹:递归
13
网络通信
TCP协议下的数据交换是通过Socket(套接字)方式实现的,发送者和接受者都必须使用,面向连接 可靠
Socket建立连接。 对应的 ServerSocket用于服务器端 Socket用于客户端
UDP是一种无连接协议,以数据报形式传输数据, 面向非连接 不可靠 对应DatagramSocket
端口
反射:反编译动态的获取和创建
java.lang.Class;
java.lang.reflect.Constructor;
java.lang.reflect.Field;
java.lang.reflect.Method;
java.lang.reflect.Modifier;
用Class(字节码)来管理类,
注:
一个类中只有一份字节码文件不管是用下面何种方法获取都一样
获取字节码对象的三种方式①使用类名获取.class() ②使用对象获取 new一个对象然后.getClass() ③通过字符串获取 class.forName(“类的全路径”);
获取字段
设置字段/调用方法
Class类的实例表示正在运行的Java应用程序中的类和接口。枚举是类,注解是接口
同一个类在内存中只有一个字节码对象
相对路径:淘汰掉长的file路径
类加载器:ClassLoader
绝对路径:相对当前目录的
Comparable接口 比较器
JVM(java虚拟机)
JVM是一种软件模拟出来的计算机,用于执行java程序,是java跨平台特性的依赖。
JVM有自己想象的硬件(处理器堆栈寄存器指令系统),它运行java就像计算机运行c/c++
垃圾回收机制
java的堆内存的释放由垃圾回收器自动运行,不能强制
Object的finalize() 一般在调用此方法之前,垃圾回收检测不在被引用的对象
System的gc() 显式的调用它可以请求的垃圾回收线程,但线程是否开始由JVM算法决定
Runtime的gc() 与System的作用相同 单例,需getRuntime()获取实例
14零散
0x0d和0x0a:
回车由0x0d和0x0a组成(\r \n)。 (在windows下)
回车代码:CR ASCII码:\r,十六进制0x0d,回车的作用只是移动光标至该行的起始位置;
换行代码:LF ASCII码:\n,十六进制0x0a,换行至下一行行首起始位置;
执顺序:先从父类往下执行static再把父类的东西执行完({块} 然后构造器) 最后是子类的({块} 然后构造器)
值传递:基本数据类型的,相当于复制了参数,因为是复制,所以数据量大的话效率低。
引用传递:非基本数据类型的,传递的是地址,操作的是原数据,所以修改有事会有冲突,用逻辑弥补。
xml解析
①DOM解析:把整个XML文件加载进内存进行解析
②SAX解析:通过流的形式一行行解析
第二部分2018.5.18
字符串
String.join(符号,字符串,字符串); 用符号分隔字符
不可变字符串的优点:编译器可以让字符串共享:公共的字符串存储池
equalsIgnoreCase()不区分大小写的equals
字符串构建器:
StringBuilder:前身是StringBuffer,StringBuffer效率低,但允许多线程操作。
Scanner
Scanner in = new Scanner(System.in);
String nextLine = in.nextLine();
当前的工作路径:String property = System.getProperty("user.dir");