Java 技术

Java基础知识梳理

2018-03-31  本文已影响43人  歪歪歪比巴卜

Java 基础知识梳理

1、Java的基本程序设计结构

1.1:数据类型

java中存在8中基本数据类型,其中有四种整型、2中浮点类型、一种表示unicode编码的子都单元的字符类型char和一种表示真值的boolean类型。

1.1.1 整型

整型表示没有小数部分的数值,允许正负数。java提供4种整型,如下表:

byte类型和short类型主要应用于底层文件处理或者需要控制占用存储空间的最大数组。
note:长整型数字有一个后缀L,十六进制数值有一前缀0x,8禁止有前缀0,从java7开始,加上前缀0b,就表示二进制数。从Java7开始,可以为数值字面量加下划线,使得数值更容易读,1_000_000表示100万

double的精度是float的两倍、浮点数采用的是二进制。二进制不能准确表示1/10,所以不能出现在不能有舍入误差的金融计算中。应该使用BigDecima。char类型表示单个字符。

1.1.2 数学函数Math

Math.sqrt(X) 求X得平方根
Math.pow(x,a) 计算X的a次幂
Math.sin() 计算正弦,需要弧度值
Math.cos() 计算余弦
Math.log() 计算自然对数
Math.log10() 计算以10为底的对数。

1.1.3 数值转换

可能丢失精度的转换: int->float,double->float,long->float,long->double,double->int
存在可能丢失精度的转换不能使用自动转换,必须使用强制转换。double转换为int,将截取掉double的小数位。如果要四舍五入,需要使用Math.round()方法。

2.字符串

String str = String.formate("hello %s,your salary is %d",name,salary)

3. 大数值

BigDecima和BigInteger可以分别表示任意精度的浮点数和证书。它们使用valueOf方法将一个普通数组转换成大数值对象。因为没有运算符重载。所以仅提供了add,subtract,mutiply等表示和差等操作。

4.数组

5.面向对象

6.方法参数

7. 对象构造

8.Object

9.对象包装器与自动拆装

10.枚举类

11.反射

能够分析类能力得程序称为反射。被广泛应用在JavaBeans中。

11.1 利用反射检查类的结构

概览: 在java.lang.reflect包中有三个类Field、Method、Constructor分别用于描述类的域、方法和构造器。通过Class类中的getFields,getMethods,getConstructor方法将分别返回类提供的public域、方法、和构造器数组。包括其超类的公有成员。而Class类的getDeclareFields、getDeclareMethods、getDeclaredConstructor方法将分别返回类中声明的全部域、方法和构造器、其中包括私有的成员,但不包括超类的成员。在获取了这三大类型后,可以使用其相应的方法获取更多的信息。列入获取域的类型,获取方法的修饰符,参数类型,返回值等信息。在方法和构造器中。可以通过getModifiers()方法获取获取构造器或者对象对应的修饰符。

处理域

处理方法

12.接口

13.对象克隆

class Employee implements Cloneable{
    public Employee clone() throws CloneNotSupportException{
        //call object.clone()
        Employee coned = (Employee) super().clone();
        //克隆可变对象
        cloned.hireDay = (Date) hireDay.clone();
        ...
    }
}

需要注意的是。被克隆的子对象必须都实现了Cloneable接口,否则将会抛出CloneNotSupportException异常。

14.回调

15.内部类

16.代理

17. 异常

18.泛型

    Pair<Employee> employeePair;
    Pair<String> stringPair;
    employeePair.getClass()==stringPair.getClass();//true
    Pair<T> [] pairs = new Pair<T> [10];

泛型擦除后,将会存储Object类型的对象。数组将会记住它的类型。导致真正的元素类型无法插入

19.集合

static <T> void sort(List<T> elements,Comparator<? super T> c)
该排序算法的复杂度是O(n log n)

20. 多线程

private ReentantLock myLock = new ReentrantLock();
myLock.lock()
try{
    // do something
}finally{
    myLock.unLock();
}

注意: 以银行转账的Bank对象为例,为保证原子操作。需要对Bank对象中的交易逻辑使用同步机制。每一个Bank对象都有一个对应的ReentantLock对象,只有多个线程访问同一个Bank对象时才会串行化访问。而访问不同的Bank对象时则互不影响。

class Bank{
    private Condition condition;
    ...
    public Bank{
        ...
        condition = bankLock.newCondition();
        if(...){
            condition.await();
        }else{
            ...
            condition.signAll();
        }
    }
}

调用signalAll()方法不会立即激活await的线程,只是解除了该线程的阻塞。

synchronized(obj){
    //TODO ...
}

进入此同步阻塞将获得obj的锁。

T get(): 得到这个线程当前的值,如果是首次调用get,会调用initialize来得到这个值。
protected initialize():应用覆盖这个方法来提供一个初始值。默认情况下,这个方法返回null。
void set(T t): 为这个线程设置一个新值。
void remove(): 删除对应这个线程的值

以下演示利用ThreadLocal提供SimpleDateFormate线程变量:

public static final ThreadLocal<SimpleDateFormat> dateFormat = new ThreadLocal<SimpleDateFormat>{
    protected SimpleDateFormat initalValue(){
        return new SimpleDateFormat("yyyy-MM-dd");
    }
}

//使用
String formateDate=dateFormat.get().format(new Date())

此外,Random虽是线程安全的,但是多个线程公用一个Random类会很低效。Java7提供了ThreadLocalRandom.current()调用会返回特定于当前线程的Random类实例。

public double getTotalBalance(){
    readLock.lock();
    try{
        ...
    }finally{
        readLock.unLock();
    }
}

public void tansfer(){
    writeLock.lock();
    try{
        ...
    }finally{
        writeLock.unlock();
    }
}
    public interface Callable<V>{
        V call() throws Exception;

例如Callable<String>表示一个最终返回String类型结果的异步计算。

Future保存异步计算的结果。可以启动一个计算,将Feture对象交给某个线程然后忘掉它,Feture线程的所有者再计算好结果之后就可以获得结果。

public interface Future<V>{
    V get() throws Exception;
    V get(long timeout,TimeUnit,unit);
    void cancel(boolean mayInterrupt);
    boolean isCancelled();//
    boolean isDone();//如果完成了返回true
}

有两个get方法的实现,第一个get方法调用将被阻塞,直到计算完成。第二个get方法的调用如果超时,将会抛出TimeoutException。如果计算完成,get()方法将立即返回。如果运行该计算的线程被中断,那么两个方法都将抛出InterruptException。

    Callable<Integer> cb;
    FutureTask<Integer> ft = new FutureTask<Integer>(cb);
    Thread t = new Thread(task) //包装成Runnable
    t.start
    ...
    IntegerResult result = task.get(); //包装成Future

执行器(Excutor)类有许多静态工厂方法来构建线程池,首先有如下三个:

    newCachedThreadPool();
    newFixedThreadPool();
    newSingleThreadExcutor();

newCachedThreadPool()方法创建一个可缓存的线程池,对于每个任务。如果有空闲的线程可用。立即用它执行线程,如果没有空闲的任务可用,则创建一个新的线程。newFixedThreadPool方法构建一个具有固定大小的线程池。如果提交的任务数多余空闲的线程数,则把没有得到执行的任务放置到队列当中。当其它任务完成后再运行它们。newSingleThreadExcutor是一个大小为1的线程池。由一个线程执行提交的任务。这三个方法返回实现了ExcutorService接口的ThreadPoolExcutor对象。可以用下面的三个方法之一将一个Runnable对象或者一个Callable对象提交给ExcutorService:

    Future<?> submit(Runnable task);
    Future<T> submit(Runnable task,T result);
    Future<T> submit(Callable<T> task);

其中第一个方法返回一个Future对象,可以使用这个对象来调用isDone、isCancel、isCancelled方法,但是使用get方法只是简单的返回null,第二个方法返回的Future对象的get方法返回指定类型的result对象;第三个方法传入一个Callable,并且在返回的Future对象在计算结果准备好的时候得到。

21. IO

    FileOutputStream(String name);
    FileOutputStream(String name,boolean append);
    FileoutputStream(File file);
    FileoutputStream(File file,boolean append);

需要注意的是,在FileoutPutStream中,如果append为true,那么数据将会被添加在文件尾,而具有相同名字的文件不会被覆盖。否则,会覆盖具有相同名字的文件。

    InputStreamReader in = new InputStreamReader(new FileInputStream("readme.txt"),'utf-8')
    BufferedReader bReader = new BufferedReader(new InputStreamReader(new FileInputStream('readme.txt'),'utf-8'));
    String line;
    while(line=in.readLine()!=null){
        //do something
    }
上一篇 下一篇

猜你喜欢

热点阅读