JavaSE基础知识

来源:互联网 发布:积分规则数据库设计 编辑:程序博客网 时间:2024/05/17 07:53

1.JDK/JRE/PATH

    JDK:JDK(Java Development Kit)是Sun Microsystems针对Java开发人员的产品。
    JRE:JRE(Java Runtime Environment,Java(application)的运行环境),运行JAVA程序所必须的环境的集合,包含JVM标准实现及Java核心类库。
    PATH:
        提供给操作系统寻找到Java命令工具的路径。通常是配置到JDK安装路径\bin(此目录一般存放JDK的可执行文件)
    JAVA_HOME:
        提供给其它基于Java的程序使用,让它们能够找到JDK的位置。通常配置到JDK安装路径。注意:这个必须书写正确,全部大写,中间用下划线。
    CLASSPATH :
        提供程序在运行期寻找所需资源的路径,比如:类、文件、图片等等。
    注意:在windows操作系统上,最好在classpath的配置里面,始终在前面保持“.;”的配置,在windows里面“.”表示当前路径。

2.参数传递:值传递

Java里面参数传递都是按值传递
    基本类型String作为参数传递,在调用该方法时,是按值传递的,传递值的拷贝(String传递的是引用的拷贝)。在调用该方法运行时,形参和实参是不同的变量,它们在内存中位于不同的位置,形参将实参的值复制一份,在该方法运行结束的时候形参被释放,而实参内容不会改变。
    形参类型是引用类型,在调用该方法时,是按引用传递的。运行时,传给该方法的是实参的引用,在方法体内部使用的也是实参的地址,即使用的就是实参本身对应的内存空间。所以在函数体内部可以改变实参的值。

例1:基本类型作为形参传递

public class ReferenceDemo01 {private void test1(int a){System.out.println("test1方法中得a1===" + a);a = 5 ;System.out.println("test1方法中得a2===" + a);}public static void test2(int a){System.out.println("test2方法中得a1===" + a);a = 6;System.out.println("test2方法中的a2===" + a);}public static void main(String[] args) {ReferenceDemo01 fd = new ReferenceDemo01();int a = 3 ;/** *  * 传递后,test方法对变量的改变不影响main方法中的a,只是 * 拷贝了一份main方法中的a=3到方法所在内存中,之后 * test1\test2方法中的a分别赋值为5、6 *  * */fd.test1(a);System.out.println("main方法中得a1===" + a);test2(a);System.out.println("main方法中得a2===" + a);}}

例2:引用类型作为形参传递

public class ReferenceDemo02 {private void test1(A a){//引用传递/** *  * 拷贝类A的引用a,此时的a.age已经被改变(main方法中a.age=10), * 对(引用)a的操作会引起堆内存中a对象的改变 *  * */System.out.println("test1方法中得age1===" + a.age);a.age = 20 ;//改变对象a的属性ageSystem.out.println("test1方法中得age2===" + a.age);}public static void main(String[] args) {ReferenceDemo02 fd = new ReferenceDemo02();A a = new A();System.out.println("main方法中得age1=" + a.age);//初始时a.age为0a.age = 10 ;//改变a中age的值System.out.println("main方法中得age2=" + a.age);fd.test1(a);//传递的是方法对a中属性修改后的age值System.out.println("main方法中得age3=" + a.age);}}class A{public int age = 0 ;}
3.Java中的数据类型

    Java中,数据类型的范围与运行Java代码的机器无关,它们都是固定的。而C和C++的数据类型依赖于具体的操作系统。并且Java中没有任何的无符号类型。
    Java中,一共有8中基本类型:4种整形、2种浮点型、1种用于表示Unicode编码的字符单元的字符类型char、1种用于表示真值的boolean类型
   注:Java中有一个能够表示任意精度的算术包,通常称为“数值”(big number)。它并不是Java中一种新的数据类型,而是一个Java对象。
基本数据类型
    |-整数类型:byte、short、int、long
    |-小数类型:float、double
    |-字符型:char
    |-布尔型:boolean
引用类型:数组、类(class)、接口(interface)

4.抽象类和接口

    抽象类是包含抽象方法的类,用abstract声明,通过继承实现,子类继承抽象类时必须覆写父类的所有抽象方法,抽象类一般用于模板设计。
    接口是一种特殊的抽象类,接口中只有public abstract修饰的方法和public static final常量(一般可以省略修饰符),用interface声明,用implements实现接口,Java语言不允许多继承,但是运用接口可以实现多继承,接口一般作为一种标准存在。
    抽象类和接口都用于抽象,通过对象的多态性产生实例化对象。

5.字符串

1、堆栈、String
  堆栈
    栈和堆都是Java用来存放数据的地方。
    Java的堆是一个运行时数据区,对象从中分配空间。堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,Java进行自动垃圾收集,存取速度较慢。
    Java栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享。缺点是,存在栈中的数据大小与生存周期必须是确定的,缺乏灵活性。栈中主要存放一些基本类型的变量(byte,int,char,boolean,double…)和对象句柄。
2、String的两种实例化方式
    String str = new String(“abc”);
    String str = “abc”;
第一种是用new()来新建对象,它会存放在堆中。每调用一次都会创建一个新的对象。
第二种是先在栈中创建一个对String类的对象引用变量str,然后查找栈中有没有存放”abc”,如果没有,则将”abc”存进栈,并令str指向”abc”,如果已经有”abc”,则直接令str指向”abc”。
3、String类对象的内容一旦初始化就不能再改变
    Java字符串就是Unicode字符序列
    Java中为字符串提供了特别的连接操作符(+),连接操作时可以把其他任何类型的数据转换成字符串,并前后连接成新的字符串。连接操作符的功能是通过StringBuffer类和它的append()方法实现的。如:
        String str = "a" + 4;
    编译时等效于
        String str = new StringBuffer().append("a").append(4).toString();
        因此字符串常量保存在字符串常量池的,操作字符串常量(如+、substring())后产生的结果并不是共享的
        JDK API源代码:
        public final class String  implements java.io.Serializable, Comparable<String>, CharSequence{...}
        public final class StringBuffer extends AbstractStringBuilder implements java.io.Serializable, CharSequence{...}
        注:final修饰类时不可以继承
4、StringBuffer的容量
    StringBuffer类用于内容可以改变的字符串,一旦通过StringBuffer生成了最终想要的字符串,就应该使用StringBuffer.toString()方法将其转换成String类,随后就可以使用String类的各种方法操纵这个字符串了
    StringBuffer是基于字符的容器,它的增长原则实际上是用来控制字符串的长度和容器容量之间关系的。所谓的长度是指字符串类型中字符的个数。而容量是存储这些字符的字符数组(char[])的大小。长度由length()方法返回,而容量由capacity()方法返回。
    StringBuffer类有4个构造方法:
        默认构造方法public StringBuffer():构造一个不带字符的字符串缓冲区,初始容量为16个字符(一种工业标准)。换句话说,用于存储字符串的char[](或缓冲区)的创建形式如下所示:
            char[] buffer = new char[16];
    容量的确定:
        构造方法:StringBuffer(int capacity)  构造一个不带字符,但具有指定初始容量的字符串缓冲区。当传入的值小于默认值(16)时,使用默认值;如果大于默认值,默认值加倍。容量为加倍后的默认值与传入的参数的较大者。
        JDK API源代码:
         public synchronized int length() {
            return count;
         }
         public synchronized int capacity() {
            return value.length;
         }
         public synchronized void ensureCapacity(int minimumCapacity) {
            if (minimumCapacity > value.length) {
                expandCapacity(minimumCapacity);
            }
          }
Java编程语言中,总是使用右开区间来传递索引范围,所以“到达的(to)”索引值是不包括在内的。

6.多线程
线程与进程
    线程:(可拥有资源的独立单位,可独立调度和分配的基本单位),线程是进程中得一个实体,是被系统调度和分配的基本单位,它可与同属一个进程的其他线程共享进程所拥有的全部资源。
调用run()方法将顺序执行线程,并没有启动线程,要启动线程是不能调用run()方法的(调用run方法是方法的调用),而 应该是调用从Thread类中集成而来的start()方法(start方法是个本地方法,控制线程的启动);启动线程时调用的是start()方法,但实际上调用的却是run()方法的主体;启动多线程,抢占CPU资源运行自己
线程的状态
    创建-->就绪-->运行-->堵塞-->死亡
    线程操作的相关方法:(查找JDK API)
        Thread类中的主要方法:
            取得和设置线程名称:getName()、setName()
            判断线程是否启动:isAlive()
            线程的强制运行:join()
            线程的休眠:直接使用Thread.sleep()
            中断线程:interrupt()
            后台线程:setDaemon()
            线程优先级:一些静态常量
            线程的礼让:yield()
Java程序每次运行至少启动几个线程
    两个:main线程(优先级是:NORM_PRIORITY)、垃圾收集线程
同步与死锁、生产者与消费者
    Java是多线程的编程语言,多线程有一个很重要的特点就是可以实现资源共享,Java中通过继承抽象类Thread或者实现Runnable接口,覆写run()方法,并通过start()方法启动线程,但是由于每个线程都以各自独立的、不可预知的速度向前推进(运行),当多个线程间合作时就会产生干扰问题,即产生同步。
    死锁是指两个以上的线程互相都要求使用对方已经占用的资源而导致无法继续运行的现象。

    产生死锁的原因:

    ①推进顺序不当(执行速度、时机未知)
    ②同类资源分配不当(资源数小于线程所要求的总数)
    ③PV操作使用不当
    两个问题:
        1、生产者不断生产,消费者不断消费,有可能第一种信息还没生产完就被消费者取走了,信息不准确连贯
        2、重复生产、重复取走
     解决:(在信息类中做修改)
        在同一段时间内,只能生产或者只能消费(同步)
            在任何时间段内都只能等待生产者生产的某种信息被消费者取走后才能继续生产(线程等待、唤醒:设置标志位flag为true时表示缓冲区空,可以生产产品送入缓冲区)