一、.内部类:成员式内部和局部式内部类
1. 成员式内部类:包括静态内部类和成员类别类
1) 静态内部类:
package abc; class Outter{ static class Inner{ } }
完整类名是abc.Outter.Inner,编译后是Outter$Inner.class。外部类加载时静态内部类随之加载,但静态内部类无法访问外部类的非静态成员,它和外部类几乎是独立的,可以在没有外部的情况下,单独创造一个内部类对象。
总结一下,静态内部类和外部类仅仅是包括关系,缩小了命名空间本质上是两个独立的类,JVM也不知道它们两个有包括关系。
2).成员内部类
package abc; class Outter{ class Inner{ } }
内部类需要等外部类创建了对象以后才会被加载到JVM中,它属于外部类的某个实例,因此可以访问外部类的静态和非静态成员。创建时使用如下语法:
public staic void main(String[] args){ Outter o = new Outter(); Outter.Inner i = o.new Inner(); }
系统会为成员内部类的构造方法自动加上一个外部类的参数以及一个外部类的成员变量,这是为了遵循先有外部类实例才能有内部类实例的原则。代码如下:
class Inner(Outter o){ this.o = o; }
2 局部式内部类:包括普通局部内部类和匿名内部类
1)局部内部类:
public void adc(){ class MyLocal{ } }
局部内部类也是独立的类,只不过它的使用受到了限制。例如,不能使用static关键字,只能使用final和abstract关键字,仅可以访问外部类带有final的局部变量,也可以访问任意外部类对象的成员变量。
定义在静态方法中就相当于静态内部类;定义在普通方法中相当于成员内部类。
2)匿名内部类:
public void adc(){ new OneInterface(){ public void interMethod(){ ... ... } } }
没有名字的局部内部类。外部无法直接使用它。编译后的名字类似Outter$1.class
二、语法基础
1. 关键字作用范围
public:类内部、本包、子类、外部包;
protected:类内部、本包、子类;
default:类内部、本包;
private:类内部;
2.堆和栈
栈(stack):主要保存基本类型(或者叫内置类型)(char、byte、short、int、long、float、double、boolean)和对象的引用,数据可以共享,速度仅次于寄存器(register),快于堆。
堆(heap):用于存储对象。
三、数据类型
1. int和Integer
int:基础数据类型,占4个字节,一般创建时保存在栈内存中,可以用算术运算符进行加减乘除等操作。在参数传递时直接传递值;
Integer:本质上是一个类,创建时在堆内存中开辟一块新空间。算术运算符不能直接操作它(需要拆箱),参数传递时传递引用。
2. long、float、double
long:8个字节,取值范围是:-2的63次方~2的63次方-1
float:4个字节,取值范围是:3.4E+10的-38次方~3.4E+10的38次方
double:8个字节,取值范围是:1.7E+10的-308次方~1.7E+10的308次方
3.boolean
1)Java不能用非0表示true,也不能用0表示false,只能用布尔型的true和false来进行条件判断。注意Boolean除了true和false外,还有null。
四、数组和集合的使用
1. 数组
1)new Object[5]并没有创建5个对象,而是创建了长度为5的数组,里面有5个null对象。
2)二维数据:先创建一维数组,然后该数组的元素在引用另外一个一维数组。因此二维数据各元素的长度可以不一样。
2.HashTable和HashMap的区别
1) HashTable的方法是同步的,HashMap不能同步,类似Vector和ArrayList;
2) HashTable不允许null值(key和value都不允许),HashMap允许null值(key和value都可以);
3)HashTable使用Enumeration遍历,而HashMap使用Iterator进行遍历;
4)HashTable中hash数组默认大小是11,增加方式是:old*2+1。HashMap中hash数组的默认大小是16,而且一定是16的指数。
5)哈希值的使用不同,HashTable直接使用对象的hashCode,而HashMap会重新计算hash值。
五、多线程编程
1.线程和进程的区别
1) 线程的划分粒度小于进程,线程隶属于某个进程。
2)进程是程序的一种动态形式,是CPU、内存等资源占用的基本单位,而线程是不能独立地占有这些资源的;
3)进程这间相互独立,通信比较困难,而线程之间共享一块内存区域,通信比较方便;
4)进行在执行过程中,包含比较固定的入口、执行顺序和出口,而线程的这些过程会被应用程序所控制。
2.Runnable接口与Thread类的主要区别
1)线程类继承自THread 相对于Runnable来说,使用线程的方法更方便一些;
2)实现Runnable接口的线程类的多个线程,可以更方便地访问同一变量,而Thread类则需要内部类进行替代。
六、Java的反射
1.利用反射实例化一个类
无参的构造方法,可以用Class的newInstance()来创建;有参的构造方法需要用java.lang.reflect.Constructor类,比较麻烦。所以一般为每个类提供一个无参的构造方法,再通过setter进行设置。
2.利用反射访问一个类的私有成员
public class PrivateTestClass { static class PrivateTest{ private String field; public PrivateTest(String field) { super(); this.field = field; } } public static void main(String[] args) throws Exception { PrivateTest obj = new PrivateTest("hello"); Class clazz = obj.getClass(); Field f1 = clazz.getDeclaredField("field"); f1.setAccessible(true); System.out.println(f1.get(obj)); } }
七、网络通信
1. UDP通信特点
1) UDP是一个无连接协议,传输数据之前源端和终端不建立连接,当它想传送时就简单地去抓取来自应用程序的数据,并尽可能地把它扔到网络上。
2)i需要维护连接状态,包括收发状态等。
3)字节开销很小。
4)吞吐量主要受应用软件生成数据的速率、传输带宽、源端和终端主机性能等因素的限制。