1.一个单例模式的实例:
/**
*设计模式:单例模式--类的计划生育(只生一个好!)
* 一、什么是单例模式:
* Singleton是一种设计模式,高于语法,可以保证一个类仅有一个实例,并提供一个访问它的全局访问点。
*
* 二、单例模式的特点:
* 1.私有构造--不能在外部通过NEW得到实例;
* 2.私有、静态属性--唯一对象;
* 3.公共静态方法得到静态属性。
*
* 三、实现单例模式的原理:
* 利用类的属性(静态变量)在系统中唯一的特性,
* 建立这样一个唯一的引用并控制这个引用所指的空间是不变的。
* */
public class SingleT {
private static SingleT st; //唯一对象(全局访问点);
private SingleT(){ // 私有构造;
}
public static SingleT getNewInstance(){ //静态方法返回对象;
if(st == null){ //在多线程的情况下,可能会产生多个实例,需要加synchronized来保证线程安全;
st = new SingleT();
}
return st;
}
public String toString(){
return "SingleTon Mode:" + getClass().getName(); //重写object 的toString()方法;
}
}
public class SingleT {
private static volatile SingleT st = null; //唯一对象
private SingleT(){} //私有构造
public static SingleT getInstance(){ //
if(st==null){
synchronized(SingleT.class){ //多线程单例-双重检查锁定
if(st==null){
st = new SingleT();
}
}
}
return st;
}
}
public class Singleton2 { //静态内部类型形式的单例
private Singleton2(){}
public static final Singleton2 getInstance(){
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder{
private static final Singleton2 INSTANCE = new Singleton2(){};
}
}
/**
* 网络套接字Socket(TCP)
* 1、一个Socket相当于一个电话机;
* OutputStream -->相当于话筒;
* InputStream -->相当于听筒;
* 2、服务器端要创建的对象:java.Net.ServerSocket
* 3、创建一个TCP服务器端程序的步骤:
* a).创建一个ServerSocket
* b).从ServerSocket接受客户连接请求
* c).创建一个服务线程处理新的连接
* d).在服务线程中,从socket中获得I/O流
* e).对I/O流进行读写操作,完成与客户的交互
* f).关闭I/O流
* g).关闭Socket
*/
public class TServer { //例子中做为接受数据方
public static void main(String[] args){
try{
ServerSocket server = new ServerSocket(8891);
while(true){
Socket socket = server.accept();
InputStream is = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is)); //读取客户端发送来的文本内容
FileWriter fw = new FileWriter("c:\\server.text"); //将客户端发送到文本内容保存到文件
BufferedWriter bw = new BufferedWriter(fw);
String s = br.readLine();
bw.write(s);
br.close();
bw.close();
socket.close();
}
}catch(Exception e){
e.printStackTrace();
}
}
}
* 创建一个TCP客户端程序的步骤:
* 1).创建Socket
* 2).获得I/O流
* 3).对I/O流进行读写操作
* 4).关闭I/O流
* 5).关闭Socket
*/
public class TClient { //例子中做为发送数据方
public static void main(String[] args){
try{
Socket socket = new Socket("localhost",8891); // 建立TCP连接,期间包括三次握手的过程
OutputStream os = socket.getOutputStream();
BufferedWriter bw = new BufferedWriter( new OutputStreamWriter(os));
bw.write("for test"); //发送文本
bw.close();
os.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
3.分页查询:
1) oracle分页查询:取工资第5~10名的员工(二重子rownum语句,取别名)
select rn,id,last_name,salary From (
select id,last_name,salary,Rownum rn From (
select id,last_name,salary from
s_emp order by salary desc) where rownum <= 10)
where rn between 5 and 10
2) mysql分页查询:
select * from product limit 0,5; ("limit 0,5--> 从记录0开始,取5条记录。")
3) DB2 分页查询:
提取第10条到第20条的记录:
select * from (
select 字段1,字段2,字段3,rownumber() over(
ORDER BY 排序用的列名 ASC) AS rn from 表名)AS a1 where a1.rn between 10 and 20
4)SQL Server 分页查询:
选择从10到15的记录
select top 5(页大小) * from (select top 15 * from table order by id asc) table_别名 order by id desc
select TOP 页大小 * from table where id > (select isnull(max(id),0) from (
select TOP 页大小*(页数-1) id from table order by id) A ) order by id
4.关于System.out和System.err
public class StaticCodeTest {
static
{
System.out.println("1"); //静态代码块初始化
}
{
System.out.println("2");
}
public StaticCodeTest(){
System.err.println("3"); //构造方法
}
public static void main(String[] args){
new StaticCodeTest();
}
}
输出结果:123;
System.out是标准输出,一般都带有缓存。需要缓冲几个字符再输出;而System.err是标准错误输出,默认是不带缓存的。不需要缓冲,立即输出。
system.out用于标准日志的输出,而system.err用于标准错误的输出。
5.JVM运行期数据区:
1). PC寄存器:
每个JVM线程都有自己的PC(程序计数器)寄存器。JVM的PC寄存器占一个字宽(主机平台上一个指针的大小)。
JVM字的概念:一个字的通常大小是主机平台的一个指针的大小。若是32位平台,字是32位,指针也是32位的。
2). Java栈(Stack):
每个JVM线程都有一个私有的,与线程同时创建的Java栈。栈可以是不连续的,也可以是动态扩展的。
a.若线程中的计算需要比所允许的栈大的java栈,则JVM抛出:Stack Over flow Error.
b. 若Java栈可以动态扩展,并且试图扩展Java栈但没有足够的存储器来实现扩展,或者不能得到足够的存储器
为一个新线程创建初始Java栈,则java虚拟机抛出out of MemoryError.
3). Java堆(heap):
JVM中所有线程共享一个堆。堆是从中分配所有类实例和数组的存储器的运行期数据区。
4). 方法区(method area):
JVM中所有线程共享一个方法区。方法区类似于传统语言的编译后代码的存储区。
存储每个类结构以及方法和构造函数。方法区在虚拟机启动时创建。可以是固定或可扩展的;也可以是不连续的。
5) . 常量池(constant pool):
常量池是每个类或者每个接口的Java class 文件中的constant_pool表的运行期表示。每个常量池都从JVM的方法区分配。
类或接口的常量池在该类或接口的class 文件被JVM成功装载时创建。简言之,当一个方法或者变量被引用时,JVM是通过
运行时常量区来查找方法或变量在内存里的实际地址的。
6. Java的类之间的关系:
6.1. 泛化(继承):
子类获得父类的功能的同时,还可以扩展自己的功能(目的当然是代码复用)。
在Java代码表现为:继承(extends) 和 实现(implements)。
6.2. 依赖(Dependency):
两个相对独立的类A、B;当A负责构造B时,A与B形成依赖关系,即一个对象通过对另一个对象的引用去操作另一个对象。
例如:在A类中new B类的对象,然后通过这个对象的引用操作这个对象,实现了代码的复用。
6.3. 关联(Association):
两个相对独立的类A、B;当A对象持有B对象的时候,形成关联关系。关联分为:聚合(Aggregation)、组合(Composition)。
聚合、组合只有概念上的区别,在Java中的代码实现上没有区别。
6.4. 小结:
在Java中出于减少耦合度的考虑,尽量优先使用组合,而不是继承。从依赖->聚合->组合->继承,类之间的关系越来越紧密,
相互间影响也越来越大。
7.静态属性和动态属性:
动态属性属于对象,静态属性属于类。对象实例以及动态属性都是保存在Heap中的,而Heap必须通过stack中的引用(地址指针)才能被
指令(类的方法)访问到。静态属性是保存在stack中的。正因为指令和数据都是在stack中,而stack中指令和数据都是定长的。因此,很容易算
出偏移量,也因此不管什么指令(类的方法),都可以访问静态属性。也正因为静态属性被保存在stack中,所以具有全局的属性。事实上,静态
属性是保存在方法区的。stack 中只存放基本类型的数据和对对象的引用(地址指针)。
8. New一个对象时的次序:
1). 申请内存空间;
2). 执行默认初始化;
3). 执行显示初始化;
4). 执行构造中的代码;
9. this关键字:
this:在方法的内部获得当前对象的引用。本质上是一个指向本对象的指针。
1). 直接写this:代表当前对象(使用该方法的对象的引用);
2). this.xxx:访问当前对象的实例成员(仅当方法中定义有与属性同名的局部变量时,在方法中访问类的属性才需要用this.xxx);
3). this():调用本类的其他构造方法,这种用法只能出现在构造方法的第一行;
4). 不能出现在静态方法中(静态方法是类相关的,this是对象相关的);
5). this可看做一个变量,值是当前对象的引用。
10. super关键字:
super:从子类中调用父类的构造方法。
1). 与this的用法类似,只能出现在构造方法的第一行;
2). 不能出现在静态方法中(super与this都指的是对象(对象关联的),不可在static环境中使用(非对象关联));
3). super.父类中的成员名。
11. final关键字:
final类不能被继承,不能重写。final变量不可改变。
final属性初始化的时间:一在其定义处可赋值;二在构造函数中可赋值;
final的规则:
1) final变量的值不能够被改变(final一个引用,则只是该引用指向的内存空间不变,该内存空间存放的内容可以改变);
2) final方法不能被重写;
3) final类不能被继承;
说明:
final StringBuffer string = new StringBuffer("final");
final 只对引用的值即它所指向的对象的内存地址有效。final迫使引用只能指向初始的那个对象,改变它的指向会导致编译期错误。至于它所指向的对象的变化,final不负责。
12. static关键字:
static代表类相关,所有对象共享内存中一片区域。static方法或属性用来描述整个类的特征和行为,不是用来描述某个对象个体
的行为特征。static的成员创建会在类加载时完成,在创建对象之前。
static方法中,不能使用对象相关的属性或方法,也不能用this,不可有多态,不能直接访问本类非静态成员。
1) static方法:
无需本类对象即可调用此方法(非对象相关,类相关)。静态方法常为应用程序中的其他类提供实用的工具。
2) static变量(全局变量):
当声明一个对象时,不产生static变量的拷贝,而是该类所有的实例变量共同用一个static变量。所有此类实例共享次静态变量。
3) static类:
通常一个普通类不允许声明为静态的,只有内部类才可以。这时,这个声明为静态的内部类可直接作为一个普通类来使用,而
不需实例一个外部类。
13. abstract关键字:
abstract关键字可修饰类或方法,有构造但不能new。abstract方法没有方法体。
所有指向抽象类的引用,都指向非抽象的子类对象;
含有抽象方法的类必须是抽象类;
所有抽象方法,都执行子类中重写后的方法;
抽象类可以不包含抽象方法;
非抽象子类一定要重写抽象方法;
14. Interface关键字:
接口可以看成特殊的抽象类(比抽象类更加抽象);
接口中所有属性都是常量;
接口中所有方法都是抽象方法;
接口没有构造;
一个类可以实现多个接口,用Implements实现;
接口之间是多重继承(一个接口可以被多个接口继承),用extends关键字;
15. 面向对象的三大特性:
1.封装(Encapsulation)
封装的步骤:
a.所有非常量属性用private隐藏;
b.提供public方法操作属性,一般是get/set方法;
c.修改构造中的代码,改为调用set方法。
封装的特点:
a. 属性的值有效;
b. 安全性;
c. 隐藏类的细节;
d. 对外提供统一安全有效的操作属性方式;
2. 继承(Inheritance)
继承的步骤:
a.子类extends父类,每个类只能有一个直接父类;
b.逻辑上,子类必须is a父类,才能继承。
继承的特点:
a. 子类复用父类代码;
b. 继承是多态的前提条件;
c. 子类可以从父类处继承属性,非私有方法。子类无法继承构造,但是可以用super关键字调用父类构造。
super关键字在继承中的用法:
1) super.xxx:访问父类中定义的实例成员;
2) super(xxx):调用父类的构造方法,该用法只能出现在构造方法第一行。
3.多态(Polymorphism)
对象多态的概念:一个对象,多种形态;
对象多态的基础:子类对象可以当作父类对象来看;
对象多态的核心:
1) 若把子类对象当父类对象来看,那么就只能访问父类中已有定义的属性和方法;
2) 若子类把父类的方法(非静态方法)覆盖,再把子类对象当做父类对象来看,去调用该方法,调用的是覆盖之后的方法(子类中定义的方法);
3) 多态主要用于参数设计和方法返回设计。
分类:
a.方法的多态:重载(Overloading)和重写(Overriding)。
重载:是在一个类中多态性的一种表现;
重写:是父类与子类间多态性的一种表现。
b.类、接口的多态:父类引用可以指向父类或子类的对象。
修订:
2017年3月14日 更正关于单例模式的相关理解及代码,参考:http://geek.csdn.net/news/detail/186671
参考:
注: