黑马程序员--Java基础--java语法基础

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-

1、标示符:程序中自定义的名词,比如说:类名,变量名,函数名,包名等。。
这些名字中的字符包含:数字:0~9;26个大小写字母;以及$和_。
注意:标示符定以时要遵循以下规则。
1.不能以数字开头。
2.不能使用关键字。

2、变量:内存中的存储空间,用来存储常量数据的。
开辟变量空间三要素:
1. 数据类型。
2. 变量名称。
3. 变量初始化值。
变量的好处:方便于运算,且变量空间可以重复使用。
那么什么时候定义变量呢?当有些数据不确定时,就定义变量。

既然变量时内存中的空间,那么它就有作用域和生命周期。
1.变量的作用域:从定义变量位置开始到该变量所在的一对大括号结束。
2.变量的生命周期:从定义变量开始到它所在的作用域结束。

3、常量:存储的是在程序中不会发生变化的数据。只能赋值一次,不可以被改变。

4、关键字:就是被java赋予特殊含义的单词。特点:所有字母都是小写。
保留字:还没有赋予特殊含义,但是打算在后期使用的单词。

那么关键字有哪些呢?

1. 用于定义数据类型的:
byte short char int long float double boolean void class interface

2、 用于定义数据类型值:
true false null

3、 用于定义流程控制的:
if else for do while switch break continue case return default

4、 用于定义访问权限修饰符:
private public protected

5、 用于修饰类、函数、变量的:
abstract static final synchronized

6、 用于定义类与类之间的:
Extends implements

7、 用于建立实例对象、引用实例和 判断实例:
new this super instanceof

8、 用于异常处理:
Try catch finally throw throws

9、 用于定义包和导入包的:
package import

10、 其他修饰符:
native strictfp transient volatile assert

5、数据类型:
1.基本数据类型:byte short char int long float double Boolean
2.引用数据类型:数组、类、接口。
整数默认类型是:int
小数默认类型是:double

级别(由小到大):byte short char 这三个同级。
int
float
long
double
自动类型转换 :从级别低到级别高的,系统自动转换。
强制类型转换:从级别高的到级别低的。就是把一个级别高的赋值给级别低的时候使用。
使用方法:(转换后的类型)转换前的类型;如:(byte)int类型

代码演示:

class Demo 
{
    //类型的自动和强制转换。
    public static void main(String[] args) 
    {
        byte b = 4;
        short s = 3;
        int d = 5;
        d=b+s;//这是数据类型的自动转换。
        //b=b+s;//这句代码会报错。错误: 不兼容的类型: 从int转换到byte可能会有损失。
        //原因是因为b+s的结果为int类型的,不能自动转换成byte类型,
        b=(byte)(b+s);//这就是数据类型的强制类型转换。
        System.out.println(b);//结果为7.
        System.out.println(d);//结果为7.
    }
}

6、运算符号:

1.算数运算符:+ - * ++ – / %(取模:任何整数模2不是0就是1,这样可以用于开 关运算,只要改变被模数就可以。)
+:连接符。
++ –:分为两种情况。一种是在前,一种是在后。如:++a,a++.—a,a–.

2.赋值运算符:= += -= *= /= %=

3.比较运算符:< > == <= >= != 运算后的结果不是true就是false。

4.逻辑运算符:& | ! ^ && || 除了!外,其他的逻辑运算符连接的都是两个boolean型的表达式。
&: 两边都为true时,结果为true,否则false。
|: 两边都为false时,结果为false,否则为true。
^ (异或):和或有点不一样,两边都一样,结果为false。
两边结果不一样,结果为true。

& 和 && 的区别:
&:无论左边结果是什么,右边都参与运算。
&&(短路与):只要左边为false,那么右边就不参与运算。

| 和 || 的区别:
|:无论左边结果是什么,右边都参与运算。
||(短路或):只要左边为true,那么右边不参与运算。
5.位运算符:用于操作二进制位的运算符:

(右移) <<(左移) >>>(无符号右移)
例如:如何高效的算出:2*8. 2<<3.
例如:对两个变量的数据互换:要求不使用第三方变量。
int a=3,b=5;结果为:b=3,a=5;
一般解决办法(使用第三方变量):
int temp =0;
temp = a;
a = b;
b = temp;

不使用第三方变量:
利用加减原理:
a = a + b; a = 8;
b = a - b; b = 3;
a = a - b; a = 5;

异或原理:一个数异或另一个数两次,结果还是那个数。
a = a ^ b;
b = a ^ b;//b = a ^ b ^ b = a
a = a ^ b;//a = a ^ b ^ a = b;
代码演示:
需求:将一个整数装换成不同的进制,用函数的重载形式来完成。

    public class JinZhiTrans
    {
    //这是一个空参数的构造函数,private的目的是不让改类创建实例对象。
    private JinZhiTrans(){}
    /**
    这是将十进制转成二进制。
    @param num 传入一个十进制的整数。
    */
    public static void toBin(int num){
        trans(num,1,1);
    }
    /*
    十进制转八进制:
    */
    /**
    这是将十进制转成二进制。
    @param num 传入一个十进制的整数。
    */
    public static void toBa(int num){
        trans(num,7,3);
    }
    /*
    十进制转十六进制:
    */
    /**
    这是将十进制转成二进制。
    @param num 传入一个十进制的整数。
    */
    public static void toHex(int num){
        trans(num,15,4);
    }
    /*
    抽取出来的相同功能函数。定义成一个功能。
    */
    private static void trans(int num,int base,int offset){
        if (num==0){
        System.out.println(num);
        return ;
        }
        char[] ch={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
        char[] arr= new char[32];
        int pos = arr.length;
        while (num!=0)
        {
        arr[--pos] = ch[num&base];
        num = num >>>offset;
        }
        for (int i=pos;i<arr.length;i++ )
        {
        System.out.print(arr[i]);
        }
    }
}

7、语句。
1.用于循环的语句:
a)for循环。
b)while循环。
c)do while循环。

2.用于判断的语句。
a)if判断语句。
b)switch 选择判断语句。(当判断的是固定个数的时候建议用switch语句。效 率相对较高。)

3.这些语句的固定格式:
A)
for(初始化表达式;循环条件表达式;循环后的操作表达式){
执行语句;
}

B)
While(循环条件表达式){
执行语句;
}

C)
do{
执行语句;
}while(循环条件表达式)

D)
1.if(条件表达式){
执行语句;
}
2.if(条件表达式){
执行语句;
}else{
执行语句;
}
3.if(条件表达式){
执行语句;
}
else if(条件表达式){
执行语句;
}
……
else{
执行语句;
}

E)
switch(表达式){
case 取值1:
执行语句;
break;
case 取值2:
执行语句;
break;
……
default:
执行语句;
break;
}
对选择判断的说明:
用小括号中的变量字依次和case所对应的值进行比较,和哪个case所对应的值相等,就执行哪个case后的语句,如果没有和case所对应的值相同,则执行默认default下的语句。

switch代码演示:
需求:游戏俄罗斯方块,当出现不同的方块,调用不同的方块变形和旋转方法(具体变形和旋转的功能可以 不写),并要使用多线程来完成。
数值0时,是T型。
数字1时,是田型。
数字2时,是L型。
数字3时,是|型。
数字4时,是Z型。

import java.util.*;
class FangKDemo 
{
    public static void main(String[] args) 
    {

        FangKuaiDemo fk = new FangKuaiDemo();//创建一个方块类的对象。

        Thread t1 = new Thread(fk);//创建一个新线程。
        Thread t2 = new Thread(fk);//创建一个新线程。
        Thread t3 = new Thread(fk);//创建一个新线程。
        Thread t4 = new Thread(fk);//创建一个新线程。
        Thread t5 = new Thread(fk);//创建一个新线程。

        t1.start();//启动一个线程。
        t2.start();//启动一个线程。
        t3.start();//启动一个线程。
        t4.start();//启动一个线程。
        t5.start();//启动一个线程。
    }
}

//方块类。定义了产生不同方块的函数和对应的变形、旋转的函数,并集成Runnable接口,实现多线程。
class FangKuaiDemo implements Runnable
{
    //产生不同方块的函数。
    public static int FangKuai(){
        //创建一个产生随机数对象。
        Random d = new Random();
        //产生0~4  这5个随机数。
        return d.nextInt(5);
    }
    //T型方块变形和旋转的函数。
    public static void t(){
        System.out.println("我是 T 型,开始变形和旋转。");
    }
    //田型方块变形和旋转的函数。
    public static void tian(){
        System.out.println("我是 田 型,开始变形和旋转。");
    }
    //L型方块变形和旋转的函数。
    public static void l(){
        System.out.println("我是 L 型,开始变形和旋转。");
    }
    //|型方块变形和旋转的函数。
    public static void shu(){
        System.out.println("我是 | 型,开始变形和旋转。");
    }
    //Z型方块变形和旋转的函数。
    public static void z(){
        System.out.println("我是 Z 型,开始变形和旋转。");
    }
    public void run(){
        for循环用来实现多次调用的功能。
        for(int x=0;x<100;x++){
            System.out.println(Thread.currentThread().getName());//获取执行该方法的线程名称。
//既然判断的次数是固定的,那么我们可以使用选择判断来实现该功能。
            switch(FangKuai()){
                case 0://返回的数值为0时,调用T型方块函数。
                    t();
                    break;
                case 1://返回的数值为1时,调用田型方块函数。
                    tian();
                    break;
                case 2://返回的数值为2时,调用L型方块函数。
                    l();
                    break;
                case 3://返回的数值为3时,调用|型方块函数。
                    shu();
                    break;
                case 4://返回的数值为4时,调用Z型方块函数。
                    z();
                    break;
                default ://如果返回的数值不是0~4之间的,则就报异常.
                    throw new RuntimeException("程序运行错误。请检查!");
//这里可以不用写break,因为当执行到throw new RuntimeException("程序运行错误。请检查!")
//这句代码的时候程序就已经停止了,下面的代码根本不会被执行到。
            }
        }
    }
}

注意:
1.break是可以省略的,如果省略了一个,则会一直执行 到下个break为止。
2.switch小括号里面的变量须为byte short int char四中类型中的一种。
3.default可以写在switch结构中的任意位置,但是如果放在结构中的第一行时,不管值是否和case的值相同,都会从default开始执行,直到执行到第一个break出现为止。
4.当判断的结果为boolean类型时,需要用if语句。
5.当某些语句需要被执行很多次时,需要用循环结构。
6.While和for可以互换:区别在于如需要定义变量用来控制循环次数,建议使用for循环,因为for循环结束后变量在内存中被释放。
7.break:用在循环和switch(选择判断)中,当单独存在时,下面不要定义其他语句,因为执行不到,编译会失败。当break在嵌套循环中时,跳出的只是当前循环,如果想要跳出外层循环,需要给外层循环做个标记即可。
8.continue:只能用于循环中,意思是结束本次循环,继续下次循环。当continue单独存在时,下面不可以定义其他语句,因为执行不到。

代码演示:
打印长方形时,外循环控制的是长方形的行数,内循环控制的是长方形的列数。

for (int x = 0;x<4 ;x++ )
    {
        for (int y = 0;y<3 ;y++ )
        {
            System.out.print("*");
        }
        System.out.println();
    }

当打印的图形形状的尖朝上时。内循环的条件表达式是小于外循环的数值。

for (int x=0;x<5 ;x++ )
    {
        for (int y = 0;y<x ;y++ )
        {
            System.out.print("*");
        }
        System.out.println();
    }

当打印的图形形状的尖朝下时。内循环的初始化值为外循环的值。

for (int x =0;x<5 ;x++ )
    {
        for (int y =x;y<5 ;y++ )
        {
            System.out.print("*");
        }
        System.out.println();
    }

8、函数:完成一个功能往往需要一些代码来实现,而要再实现这个功能,则需要重复这些代码,为了提高代码复用性,则将这些代码定义成固定的功能,这个功能就是java中所谓的函数。
定义函数的格式:
修饰符 返回值类型 函数名称 (参数类型 形式参数1,参数类型 形式参数 2,参数类型 形式参数3 …… ){
执行语句;
return 返回值;
}
代码演示:
我们经常写的这个就是函数:
Public static void main(String[] args){
要执行的语句;
}
以上这个就是主函数。
主函数的作用:
1.保证该类的独立运行。
2.程序的入口。
3.被jvm调用。

注意:当函数没有具体的返回值时,返回值类型用void关键字表示,此时return语句可以省略不写,因为系统会自定加上。
return 的作用:结束函数,结束功能。

那么什么时候定义函数呢?
定义函数其实就是定义功能,定义一个函数就是实现一个功能。通过两个明确来完成。
1.明确该功能运算完的结果,就是在明确返回值类型。
2.明确该功能在运算时是否有未知内容参与运算,就是在明确该函数的参数列表(参数类型和参数个数)。

函数的作用:
1.定义功能。
2.封装代码,提高代码的复用性。
注意:函数中只能调用函数,不能定义函数。

那么为什么定义函数要定义函数名呢?
1.给功能做一个标示,方便于调用。
2.通过函数名称可以明确该函数的功能,方便于程序阅读。
注意:既然是定义函数,那么肯定会有重名的时候,那么怎么区分这些重名的函数呢?
通过函数参数的个数,或者参数的类型不同,通过这些来区分的。这种区分方法叫做函数的重载。

函数的重载只看参数列表和参数类型,和返回值类型无关。
函数重载形式代码演示:

class Demo{
        pubic static void main(String[] args){
            //下面的三个函数就是函数的重载形式。
            //只是参数个数不同和参数类型不同。而函数名称则完全形同。
        }
        public static void printArr(int[] arr){
            //取出数组中的各个元素。
            for (int x =0;x<arr.length;x++){
            //调用打印功能的函数。
            sop("arr["+x+"]="+arr[x]+";");
            }
        }
        public static void printArr(int[] arr1,int[] arr2){
            for (int x =0;x<arr1.length;x++){
                //调用打印功能的函数。
                sop("arr["+x+"]="+arr1[x]+";");
            }
            for (int x =0;x<arr2.length;x++){
                //调用打印功能的函数。
                sop("arr["+x+"]="+arr2[x]+";");
            }
        }
        public static void printArr(String[] arr){
            System.out.println(arr);
        }
}
代码演示简单的函数创建和调用:
class Demo 
{
        //创建一个数组,并取出数组中的各个元素。
        public static void main(String[] args) 
        {
            //创建一个int类型的数组。
            int[] arr = new int[4];
            //将元素存储到数组中。
            arr[0] = 2;
            arr[1] = 7;
            arr[2] = 9;
            arr[3] = 0;

            //调用创建好的打印数组的函数。
            printArr(arr);
        }
        //创建一个简单的打印功能的函数。
        public static void sop(Object obj){
            System.out.println(obj);        
        }
        public static void printArr(int[] arr){
            这里要注意的是:函数内只能调用函数,不能创建函数。       

            //取出数组中的各个元素。
            for (int x =0;x<arr.length;x++){
                //调用打印功能的函数。
                sop("arr["+x+"]="+arr[x]+";");
            }
        }
}

9、数组。
数组就是一个容器,存储同一种数据类型的容器。用于封装数据,从0开始,是一个具体的实体。
创建数组的格式:
1.元素类型[] 数组名称 = new 元素类型[元素个数];
2.元素类型[] 数组名称 = new 元素类型[]{element1,element2,element3……};
3.元素类型 数组名称[] = new 元素类型[元素个数];
4.元素类型[] 数组名称 = {element1,element2,element3……};

代码简单演示数组的创建和取出数组中的元素:
class ArrayDemo 
{
    //要求:创建一个数组,并取出数组中的各个元素。
    public static void main(String[] args) 
    {
        //创建一个int类型的数组。
        int[] arr = new int[4];
        //将元素存储到数组中。
        arr[0] = 2;
        arr[1] = 7;
        arr[2] = 9;
        arr[3] = 0;

        //取出数组中的各个元素。
        for (int x =0;x<arr.length;x++){
            System.out.println("arr["+x+"]="+arr[x]+";");
        }
    }
}

Java 内存空间分配情况:
1.寄存器 2.本地方法区 3. 方法区 4.堆 5.栈
在这里只做对栈和堆内存的分析。
栈:存储的都是局部变量(函数中定义的变量,函数上的参数,语句中变量),只要数 据运算完成,所在的区域结束,该数据就会被释放。
堆:用于存储数组和对象,也就是实体,每一个实体都有内存首地址值。
堆内存中的变量都有默认初始化值,因为数据类型不同,所以数值也就不同。
垃圾回收机制也存储在堆内存中。

10.设计模式
在java中有23种设计模式。
设计模式:解决问题最行之有效的思想。是经过人们反复使用、分类编排和代码设计经验的总结。
使用设计模式,就是为了使代码更容易被比人理解,提高代码的重用性,保证代码的安全性。

1、单例设计模式:保证一个类在内存中,只有一个对象(既是对象唯一性)。就是解决这对象唯一性这一类问题的。
如:Runtime()方法就是使用单例设计模式来设计的。还比如:多线程读取一个配置文件时,这时就建议将配置文件封装成对象,而这个对象就需要在内存中保证它的唯一性。

那么在Java中又是怎么用代码保证对象的唯一性的呢?
思想:
1. 不让其他程序创建该类对象。
2. 在本类中创建一个本类对象。
3. 对外提供方法,让其他程序获取这个对象。
代码体现:
1. 私有化构造函数。
2. 创建私有并静态的本类对象。
3. 定义共有并静态的方法,获取这个对象。
步骤:
1.因为每一对象的创建都需要构造函数的初始化,所以只要将构造函数私有化就可以了,其他程序就无法在创建该对象了。
2.在该类中创建一个本类对象。
3.定义一个方法,来返回该对象。让其他程序都可以通过这个方法来获取到该对象(作用:可控)。
创建单例设计模式有两种方式:
1.饿汉式:就是类一加载就创建好了本类对象。
代码:

class SingleDemo1 
{
        private SingleDemo1(){}//私有化构造函数。
        private static SingleDemo1 s = new SingleDemo1();//类一加载,就创建静态并私有的本类对象。
        public static getSingle(){//对外提供静态并共有的方法,来获取到这个本类对象。
            return s;
        }

}

2.懒汉式:类加载时不创建该类对象,什么时候使用,什么时候创建该类对象。又叫延迟加载。
代码:

class SingleDemo2
{
        private SingleDemo2(){}//私有化构造函数。
        private static SingleDemo2 s = null;//创建私有并静态的本类对象引用。
        public static getSingle(){//对外提供静态并共有的方法,来获取这个本类对象。
            if(s==null)//判断本类对象的引用是否有实体指向。
                s = new SingleDemo2();//把创建本类对象的地址值赋值给本类对象的引用。
            return s;//如果本类对象的引用不为null,则直接返回本类对象。
        }
}

2、 模版设计模式:当功能内部一部分实现确定,一部分不确定。这时可以把不确定部分暴漏出去,让子类去实现。
在这里举一个例子来说明模版设计模式。
需求:要求计算出执行某一段代码的时间。代码是不确定的。
代码:

//模版设计模式:
abstract class MoBan
{
    public final void getTime(){
        long start = System.currentTimeMillis();
        code();
        long end = System.currentTimeMillis();
        System.out.println("这段代码运行了:"+(end-start)+"毫秒。");
    }
    public abstract void code();//这部分代码是不确定的,所以是抽线抽象方法,需要被子类来实现。
}
class CodeDemo extends MoBan
{   
    public static void main(String[] args){
        CodeDemo cd = new CodeDemo();//创建子类对象。
        cd.getTime();//调用父类中的getTime方法。
    }

    public void code(){//继承模版抽象类,并复写code方法。
        for (int x =0 ;x<200 ;x++ )
        {
            System.out.println(x);
        }
    }
}

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值