Java基础总结

##1.基本类型

1.在程序设计中经常用到一系列类型(基本类型),它们需要特殊对待。对于这些类型,Java采取与C和C++相同的方法,也就是说,不用new来创建变量,出是创建一个并非引用的变量,这个变量直接存储“值”,并置于堆栈中,因此更加高效。

基本类型包装类型大小
booleanBoolean-
charCharacter16-bit
byteByte8-bit
shortShort16-bit
intInteger32-bit
longLong64-bit
floatFloat32-bit
doubleDouble64-bit
voidVoid-

基本类型具有的装类,使得可以在堆中创建一个非基本对象,用来表示对应的基本类型。

public class AutoBoxingTest{
	public static final Integer CONST_A = 1;
	public static final Integer CONST_B = Integer.valueOf("2");
	public static final Integer CONST_C = new Integer(3);

	private Integer status;
	public void setStatus(Integer status){
		this.status = status;
	}
	public void displayStatus(){
		if(status==CONST_A)
			System.out.println("It's CONST_A");
		else if(status==CONST_B)
			System.out.println("It's CONST_B");
		else if(status==CONST_C)
			System.out.println("It's CONST_C");
		else
			System.out.println("Invalid status!");
	}
	public static void main(String[] args){
		AutoBoxingTest abt = new AutoBoxingTest();
		abt.setStatus(1);
		abt.displayStatus();
		abt.setStatus(2);
		abt.displayStatus();
		abt.setStatus(3);
		abt.displayStatus();
	}
}
/**
执行结果:
It's CONST_A
It's CONST_B
Invalid status!
原因:
在自动装箱和调用Integer.valueOf(String)时,返回的Integer是从IntegerCache中获取的,所以都是同一个对象。
延伸一下,如果一边是包装类,一边是基本类型时,使用< 、> 、<=等比较,都会时行值比较。
*/

Java提供了两个用于高精度计算的类:BigInteger、BigDecimal。

import java.math.BigInteger;
public class MainClass{
	public static void main(String[] argv)throws Exception
	{
		BigInteger bigInteger1 = new BigInteger("123456789012345678901234567890");
		BigInteger bigInteger2 = new BigInteger("123456789012345678901234567890");
		//add
		bigInteger1 = bigIntger1.add(bigInteger2);
		System.out.println(bigInteger1);
		//subtract
		bigInteger1 = bigInteger1.subtract(bigInteger2);
		System.out.println(bigInteger1);
		//multiplay
		bigInteger1 = bigInteger1.multiply(bigInteger2);
		System.out.println(bigInteger1);
		//divide
		bigInteger1 = bigInteger1.divide(bigInteger2);
		System.out.println(bigIntger1);
	}
}

2.基本数据类型默认值
若类的某个成员是基本类型,即使没有进行初始化,Java也会确保它获得一个默认值 。

基本类型默认值
booleanfalse
char‘/u0000’
byte0
short0
int0
long0L
float0.0L
doubl0.0d

3.javadoc
用于提取注释的一部分,输出是一个HTML文件,所有Javadoc命令只能在"/**“注释中出现,结束于”*/",使用Javadoc的方式主要有两种:嵌入式HTML或使用"文档标签","文档标签"是一些以@字符开头的命令.
####数组
Java声明数组时不能指定其长度。

int a[5]//非法
//一维数组声明方式
type var[]或type[] var;
//动态 初始化
MyType data[] = new MyType[3];
data[0] = new MyType(1,2);
data[1] = new MyType(3,4);
//静态初始化
MyType data[]={
   new MyType(1,2),
   new MyType(3,4)
};

##2.操作符
1.直接常量
为了编译器可以准确的知道要生成什么样的类型,可以给直接常量后面添加后缀字符标志它的类型,若为L表示long,F表示float,D表示double。也可以利用前缀表示进制,0x表示十六进制,0表示八进制。
2.移位操作符
(<<):向左移动,低位补0
(>>):向右移动,高位补符号
(>>>):向右移动,高位补0
3.Java中没有sizeof,因为所有数据类型在所有机器中的大小都是相同的。
##3.控制执行流程
1.foreach
是一种更加简洁的for语法用于数组和容器
for(元素类型t 元素变量x:遍历对象obj){
引用x的java语句
}

int arr[] = {1,2,3};
for(int x:arr){
	System.out.println(x);
}

运算符优先级:
(1)单目运算符+ - (正负)++ –
(2)算数运算符 * / % + -(加减)
(3)位移运算符 << >>
(4)关系运算符 > < >= <= == !=
(5)逻辑运算符 && & || | ^
(6)三目运算符
(7)赋值=
##4.初始化与清理
1.Java完全采用动态内存分配方式。每当想创建新对象时,就需要使用new关键字来构建此对象实例。
2.在构造器中,如果为this添加了参数列表,那么就有了不同的含义。这将产生对符合此参数列表的某个构造器的明确调用。(1)尽管可以用this调用一个构造器,但却不能调用两个,而且必须将构造器调用置于最起始处。(2)除构造器外,编译器禁止在其他任何方法中调用构造器。

public class Person{
	int age = 0;
	String name = "";
	Person(int a){
		age = a;
		System.out.println("age:"+age);
	}
	Person(String n){
		name = n;
		System.out.println("name:"+name);
	}
	Person(int a,String n){
		this(a);
		this.name = n;
		System.out.println("both!");
	}
}

3.finalize方法
一旦垃圾回收器准备好释放对象占用的存储空间,将首先调用其finalize方法,并且在下一次垃圾回收动作发生时,才会真正回收对象占用的内存。

public class FinalizeDemo{
	public static void main(){
		Cake c1 = new Cake(1);
		Cake c2 = new Cake(2);
		Cake c3 = new Cake(3);
		c2 = c3 = null;
		System.gc();//Invoke the Java garbage collector	
	}
}
class Cake extends Object{
	private int id;
	public Cake(int id){
		this.id = id;
		System.out.println("Cake Object "+id+" is created");
	}
	protected void finalize()throws java.lang.Throwable{
		super.finalize();
		System.out.println("Cake Object "+id+"is disposed");
	}
}
/**
执行结果 :
Cake Object 1 is  created
Cake Object 2 is created
Cake Object 3 is created
Cake Object 3 is disposed
Cake Object 2 is disposed
*/

4.在定义类成员变量的地方可以为其赋值,在C++中是不能这么做的。在类的内部,变量定义的先后顺序决定了初始化的顺序。
##访问权限
1.package必须是文件中除注释以外的第一句程序代码。
2.每个文件只能有一个public类,但是也可以完全不带public类,在这种情况下,可以随意对文件命名。
3.类的名字必须与文件名相同.
4.除了public、private、protected之外,Java有一种默认的访问权限,当没有使用前面的访问指字词时,它将发挥作用。这种权限通常称为包访问权限。在这种权限下,同一个包中的类可以访问这个成员,而包之外的类,是不能访问这个成员的。

package testcontrol;
public class MyTest{
	public int mIntPublic = 22;
	protected int mIntProtected = 33;
	private int mIntPrivate = 44;
	int mInt = 55;
	void printForAll()
	{
		System.out.println(mIntPublic);
		System.out.println(mIntProtected);
		System.out.println(mInt);
		System.out.println(mIntPrivate);
	}
}
package testcontrol;
//同一个包下的子类
class MyTestDerived extends MyTest
{
	void printForAll()
	{
		System.out.println(mIntPublic);
		System.out.println(mIntProtected);
		System.out.println(mInt);
		//Syste.out.println(mIntPrivate);
	}
}
//同一个包下的非子类
public class MyTestNotDerived
{
	public static main(String[] args){
		MyTest objMyTest = new MyTest();
		System.out.println("Access Permission Test in same package:1");
		System.out.println(objMyTest.mIntPublic);
		System.out.println(objMyTest.mIntProtected);
		System.out.println(objMyTest.mInt);
		//System.out.println(objMyTest.mIntPrivate);
		System.out.println("Access Permission Test:2");
		objMyTest.printForAll();
		System.out.println("Access Permission Test in Derived:3");
		objDerived.printForAll();
	}
}

##复用类
1.extends关键字用于类的继承。
2.在C++中,方法的动态绑定是使用virtual关键字来实现的,而在Java中,动态绑定是默认的形为,不需要添加额外的关键字。

//c++代码
class Base{
public :
	Base(){init();}
	virtual ~Base(){}
protected:
	virtual void init()
	{
		cout<<"in Base::init()"<<endl;
	}	
};
class Derived:public Base{
public:
	Derived(){init();}
protected:
	void init(){
		cout<<"in Derived::init()"<<endl;
	}
};
int main(int argc,char* argv[]){
	Base *pb;
	pb = new Derived();
	delete pb;
	return 0;
}
/*
执行结果:
in Base::init()
in Derived::init()
*/
//java
class Base{
	public Base(){init();}
	protected void init(){
		System.out.println("in Base::init()");
	}
}
class Derived extends Base{
	public Derived(){init();}
	protected void init(){
		System.out.println("in Derived::init");
	}
}
public class Test{
	public static void main(String[] args){
		Base base = new Derived();
	}
}
/*
执行结果 :
in Derived::init()
in Derived::init()
这是因为Java中的类对象在构造前就已经存在了,而c++中只有在构造完毕后才存在。
*/

3.使用关键字super显式调用基类的构造器。
4.final关键字
final可以修饰类、属性和方法。
(1)对于基本类型,final可以使其成为编译时常量,可以在定义时赋值,也可以在构造函数中进行赋值。
(2)对于对象引用,final使引用恒定不变,一旦引用被初始化指向一个对象,就无法再把它改为为指向另一个对象。

public class Bat{
	final double PI = 3.14;//在定义时赋值
	final int i;
	final List<Bat> list;
	Bat(){
		i = 100;
		list = new LinkedList<Bat>();
	}
	Bat(int ii,list<Bat> l){
		i = ii;
		list = l;
	}
	public static void main(String[] args){
		Bat b = new Bat();
		b.list.add(new Bat());
		//b.i = 25;
		//b.list = new ArrayList<Bat>();
	}
}

(3)如果用final修饰方法,可以防止任何继承类修改它的含义。类中所有的private方法都隐式地指定为final。
(4)如果用final修饰类,表示不能再继承这个类。
(5)final修饰 的成员变量必须在声明的同时或在每个构造方法中显式赋值。
##接口
1.用interface关键字创建一个接口,要让一个类实现特定接口,需要使用implements关键字。
2.接口也可以包含域,但是这些域隐式是static和final的。

interface Runner//定义接口
{
	int i = 3;
	public void start();
	void run();
	void stop();
}
interface Eater extends Runner//接口间可以继承
{
	public final static int j = 4;
	void openMouth();
	void upAndDown();
	void goIn();
}
class TT implements Eater//实现接口
{
	public void start(){System.out.println("start");}
	public void run(){System.out.println("run");}
	public void stop(){System.out.println("stop");}
	public void openMouth(){System.out.println("openMouth");}
	public void upAndDown(){System.out.println("upAndDown");}
	public void goIn(){System.out.println("goIn");}
}
public class TestInterface {
	public static void main(String[] args){
		Runner tt = new TT();
		System.out.println(tt.i);
		System.out.println(Runner.i);
		tt.start();
		Eater ee = new TT();
		System.out.println(ee.j);
		System.out.println(Eater.j);
		ee.start();
	}
}

##内部类
在一个类中定义另外一个类,这个类就叫做内部类。
1.它能访问其外围对象的所有成员。
2.如果你需要生成对外部类对象的引用,可以使用外部类的名字后面紧跟.this.
3. 使用.new创建内部类的引用

public Class Test(){
	private int num;
	public Test(int num){ this.num = num;}
	private Class Inner{
		public Test getTest(){
			return Test.this;
		}
		public Test newTest(){
			return new Test();
		}
	}
	public static void main(String[] args){
		Test test = new Test(5);
		Test.Inner inner = test.new Inner();
		Test test2 = inner.getTest();
		Test test3 = inner.newTest();
		System.out.println(test2.num);
		System.out.println(test3.num);
	}
}
/**
执行结果:
5 0
*/

##类型信息
指程序能够在运行时发现和使用类型信息,我们一般使用两种方式来实现运行时对象和类的信息:传统的RTTI和反射机制。
1.class对象
专门用来保存类的信息,所有类都是动态加载到JVM中的,在他们第一次使用的时候,类加载器会首先检查Class对象是否加载,如果没有,那么找到同名的class文件,然后加载字节码文件,验证代码的完整性和安全性,一旦这个类型的class对象加载到内存中,它将会用来创建所有此类的对象。
class对象的生成方式如下:
(1)Class.forName(“类名字符串”)
(2)类名.class
(3)实例对象.getClass()

package Refect;
class Demo{
	//other code...
}
class hello{
	public static void main(String[] args){
		Class<?> demo1 = null;
		Class<?> demo2 = null;
		Class<?> demo3 = null;
		try{
			demo1 = Class.forName("Reflect.Demo");
		}cathc(Exception e){
			e.printStackTrace();
		}
		demo2 = new Demo().getClass();
		demo3 = Demo.class;
	}
	System.out.println("类名称 "+demo1.getName());//Reflect.Demo
	System.out.println("类名称 "+demo2.getName());//Reflect.Demo
	System.out.println("类名称 "+demo3.getName());//Reflect.Demo
}

2.instanceof
告诉我们对象是不是某个特定类型的实例。
3.反射
RTTI(运行时类型信息)和反射之间真正的区别只在于,对于RTTI来说,编译器在编译时打开和检查.class文件,而对于反射机制来说,.class文件在编译时是不可获取的,所以是在运行时打开和检查.class文件。
反射主要是指程序可以访问、检测和修改它本身或行为的一种能力。

package Reflect;
interface China{
	public String name = "Rollen";
	public int age = 20;
	public void sayChina();
	public void sayHello(String name,int age);
}
class Person implements China{
	private String sex;
	public Person(){};
	public Person(String sex){this.sex = sex;}
	public getSex(){return sex;}
	public setSex(String sex){this.sex = sex;}
	@Override
	public void sayChina(){
		System.out.println("hello, china");
	}
	@Override
	public void sayHello(String name,int age){
		System.out.println(name+" "+age);
	}
}
class hello{
	public static void main(String[] args){
		Class<?> demo = null;
		try{
			demo = Class.forName("Reflect.Person")
		}catch(Exception e){e.printStackTrace();}
		//保存所有的接口
		Class<?> intes[] demo.getInterfaces();
		for(int i=0;i<intes.length;++i){
			System.out.println("实现的接口 "+intes[i].getName());
			//Reflect.China
		}
		//获得全部的构造函数
		Constructor<?> cons[]= demo.getConstructors();
		for(int i=0;i<cons.length;++i){
			System.out.println("构造函数: "+cons[i]);
		}
		//通过反射调用其它类中的方法
		try{
			Method method = demo.getMethod("sayHello");
			mehtod.invoke(demo.newInstance());
		}catch(Exception e){e.printStackTrace();}
		Object obj = null;
		try{
			obj = demo.newInstance();
		}catch(Exception e){e.printStackTrace();}
		//通过反射操作属性
		Field field = demo.getDeclaredField("sex");
		field.setAccessible(true);
		field.set(obj,"男");
	}
}

##泛型
1.通配符
(1)通配符的上界

? extends myClass其中“?”就是通配符,其上界为myClass,这句话代表myClass或其子类。
List<Apple> apples = new ArrayList<Apple>();
List<? extends Fruit> fruits = apples;

(2)通配符的下界

? super myClass表示通配符的下界为myClass,这句话代表myClass的超类型直至Object。
List<Fruit> fruits = new ArrayList<Fruit>();
List<? super Apple> = fruits;

(3)无界通配符
?等价于Object。
##注解
1.用于描述Java源代码,使得我们能够以将由编译器来测试和验证的格式,存储有关程序的额外信息。使用时在@后面跟注解的名字。
2.预定义的三个注解
(1)Override
标识某一个方法是否覆盖了它的父类的方法。
(2)Deprecated
标注一个类成员时,编译器会发出警告信息。
(3)SuppressWarnings
就是抑制编译器产生警告信息。
3.自定义注解
注解的定义和接口差不多,只是在interface前面多一个“
@”

public @interface MyAnnotation
{
}

上面的代码是个最简单的注解,这个注解没有属性。当然也可以定义有属性的注解。

public @interface MyAnnotation
{
	String value();
}

可以按如下格式使用MyAnnotation

@MyAnnotation("abc")
public void myMethod()
{
}

这里有一个约定,如果没有写属性名的值,而这个注解又有value属性,就将这个值给value属性,如果没有,就出现编译错误。
除了可以省略属性名,还可以省略属性值,这就是默认值。

public @interface MyAnnotation
{
	public String value() default "xyz";
}

可以直接使用MyAnnotation

@MyAnnotation
public void myMehtod()
{
}

4.元注解(对注解进行注解)
为注解提供了4种注解:
(1)Target
先看下面代码

@Target({ElementType.METHOD})
@interface MyAnnotation{}
@MyAnnotaion //wrong!
public class Class1
{
	@MyAnnotation //right!
	public void myMethod(){}
}

target所指的目标就是Java的语言元素,如类、接口、方法等。
(2)Retention
设置注解是否保存在class文件中

@Retention(RetentionPolicy.SOURCE)
@interface MyAnnotation{}
@Retention(RetentionPolicy.CLASS)
@interface MyAnnotation2{}
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation3{}

其中第一段代码的作用是不将注解保存在class文件中,也就是说像“//”一样在编译时被过滤掉了。第二段代码的作用是只将注解保存在class文件中,而使用反射读取注解时忽略这些注解。第三段代码的作用是将注解保存在class文件中,也可以通过反射读取注解。
(3)Documented
在默认的情况下使用javadoc自动生成文档时,注解将被忽略掉,如果想在文档中也包含注解,必须使用Documented为文档注解。
(4)Interited
在默认情况下,父类的注解并不会被子类继承,如果要继承,就必须加上Inherited注解。

@Inherited
@interface MyAnnotation{}
@MyAnnotation
public class ParentClass{}
public class ChildClass extends ParentClass{}

在以上代码中ChildClass和ParentClass一样都已被MyAnnotation注解。
5.使用反射读取注解
我们使用反射可以得到类的方法、方法的参数以及其它的类成员等信息。如果要得到某一个类或接口的注解信息,可以使用如下代码:

Annotation annotation = MyClass.class.getAnnotaion(MyAnnotation.class);
如果要得到全部的注解信息:
Annotation[] annotations = MyClass.class.getAnnotations();
或
Annotation[] annotations = MyClass.class.getDeclaredAnnotations();
getDeclaredAnnotations得到的是当前成员所有的注解,不包括继承。

##并发
1.定义任务
线程可以驱动任务,因些你需要一种描述任务的方式,这可以由Runnable接口来提供。实现Runnable接口并编写run方法。~
2.Thread类
将Runnable对象转变为工作任务的传统方式是把它提交给一个Thread构选器。
3.join方法,某个线程加到另一个线程的“尾部”,当该线程执行完后,另一个线程再继续执行。
4.yield方法,当前运行的线程退出支行状态,会变成可运行状态,使同级别的线程有机会执行,但yield不能保证任何事情。
5.wait,调用wait必须拥有对象上的锁,wait可以释放锁,wait和notify必须要成对出现。
6.当调用对象的notify方法时,它会从当前对象的“wait set”中随机通知一个线程加入排队,被通知的线程会与其它正执行的线程共同竞争对象的“锁定”。
7.wait, notify, notifyAll是Object类提供的方法,而且它们都被声明为final。
8.

###Runtime类和Process类
Runtime类封装了运行时的环境,每个Java应用程序都有一个Runtime类实例,使用应用程序能够与其运行环境相连接。通过Runtime.getRuntime()获取Runtime类的实例。Runtime类使用的是单例模式。
###集合
(1)Collection接口的iterator和toArray方法都用于获得集合中的“所有元素”。前者返回一个“iterator”对象,后者返回一个包含集合中所有元素的数组。
(2)HashSet是基于Hash算法实现的,其性能通常优于TreeSet。在我们需要排序的功能时,我们才使用TreeSet。HashSet会调用对象的hashCode()方法来获得哈希码。
(3)ArrayList内部采用数组实现,LinkedList使用“链表”来实现。
(4)LinkedHashSet不仅实现了Hash算法,可以在迭代时,按照元素加入集合时的顺序来显示对象。
(5)TreeSet使用红黑树对元素进行排序。依靠TreeMap来实现。
(6)LinkedHashMap在迭代元素时,可以按照对象加入集合的顺序来显示。
(7)TreeMap可以使用红黑树来对键对象排序。和Set类似,HashMap的速度通常比TreeMap快,只有在需要排序的功能时,才使用TreeMap。
(8)Java提供了Arrays类来封装数组。
(9)历史集合类
Vector, Stack, Enumeration,Hashtable,Properties和BitSet。
由于Vector,Stack, Hashtable, Enumeration都使用了同步机制,并发性能差。Properties和BitSet由于有着特殊用途,所以不还常使用。
###网络编程
1.TCP客户端程序与TCP服务器端程序的交互过程。
(1)服务器程序创建一个ServerSocket,然后调用Accept方法等待客户连接。
(2)客户端程序创建一个Socket并请求与服务器端建立连接。
(3)服务器接收客户的连接请求,并创建一个新的Socket与该客户建立专线连接。
(4)建立了连接的两个Socket在一个单独的线程(由服务器程序创建)上对话。
(5)服务器开始等待新的连接请求,当新的连接请求到达时,重得(2)~(5)。

2.TCP服务器程序编写
(1)调用ServerSocket()创建一个服务器端套接字,
(2)调用accept(),监听连接请求,如果客户端请求连接,则接受连接,返回通信套接字。
(3)调用Socket类的getOutputStream()和getInputStream获取输出流和输入流,开始网络数据的发送和接收。
(4)最后关闭通信套接字。
3.客户端程序编写
(1)调用socket()创建一个流套接字,并连接到服务器端。
(2)调用socket类的getOutputStream()和getInputStream()获取输出流和输入流,开始网络数据的发送和接收。
(3)最后关闭通信套接字。
4.UDP接收端编写
(1)调用DatagramSocket(int port)创建一个数据报套接字,并绑定到指定的端口上。
(2)调用DatagramPackage(byte[] buf,int length),建立一个字节数组以接收UDP包。
(3)调用DatagramSocket类的receive(),接收UDP包。
(4)最后关闭数据报套接字。
5.发送端程序
(1)调用DatagramSocket()创建一个数据报套接字。
(2)调用DatagramPacket(byte[] buf, int length,InetAddress address,int port), 建立要发送的UDP包。
(3)调用DatagramSocket类的send(),发送UDP包。
(4)最后关闭数据报套接字。
###数据库
1.JNDI
在J2EE容器中配置JNDI参数,定义一个数据源,也就是JDBC引用参数,给这个数据源设置一个名称,然后,在程序中通过数据源名称引用数据源从而访问后台数据库。
例子:

tomcatPath/conf/server.xml中的<GlobalNamingResources>节点中加入:
<Resource
auth="Container"
name="jdbc/oralce/jndi"
type="javax/sql/DataSource"<!-- jndi的接口驱动-->
driverClassName="oracle.jdbc.driver.OracleDriver"
username="test"
password="test"
maxIdle="5"
maxActive="30"
maxWait="5000"
url="jdbc:oracle:thin@127.0.0.1521:xxx"
/>

最后欢迎大家访问我的个人网站: 1024s

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值