Java基础复习(二):关键字、数据类型、强制转换、运算符、泛型

Java基础复习(二):关键字、数据类型、强制转换、运算符

注释

1.单行注释:

//单行注释

2.多行注释:

/*
*多行注释
*/

3.文档注释:

/**
 * 文档注释
 */

注意:代码本身就可以起到注释的作用,所以在命名时就尽量做到见名知意。

关键字和标识符

1.标识符:是用于给 Java 程序中变量、类、方法等命名的符号。
标识符要遵守以下规则:
(1)标识符可以由字母、数字、下划线(_)、美元符($)组成,不能包含 @、%、空格等其它特殊字符,不能以数字开头。
(2)标识符不能是 Java 关键字和保留字,但可以包含关键字和保留字。
(3)标识符是严格区分大小写的。
(4)标识符的命名最好做到见名知意。
2.Java中的关键字:
在这里插入图片描述

数据类型

数据类型分为 基本数据类型 和 引用数据类型 ,其中基本数据类型有8种,除这8种之外其他的为引用数据类型。

  1. 基本数据类型:
    在这里插入图片描述
    (1)深入理解一下基本数据类型及其包装类:
    基本数据类型与包装类之间的转换其实是装箱和拆箱的过程。装箱:自动将基本数据类型转换为包装类;拆箱:自动将包装类转换为基本数据类型。而在具体实现上,装箱过程调用包装类中的valueOf方法实现,拆箱过程是包装类中的xxxValue方法(例如:Integer.intValue)实现。
    (2)包装类常量池问题
    Byte、Short、Integer、Long:[-128,127]
    Character:[0,127]
    Boolean:True/False
    Float、Double没有实现常量池技术,所以每次创建的都是新的对象
    由于valueOf实现的不同即常量池的不同,会导致创建对象的时候可能会创建新的对象,或者是使用常量池中的对象不再重新创建对象。

java8种基本类型的自动装箱代码实现:

//boolean原生类型自动装箱成Boolean
    public static Boolean valueOf(boolean b) {
        return (b ? TRUE : FALSE);
    }
 
 
    //byte原生类型自动装箱成Byte
    public static Byte valueOf(byte b) {
        final int offset = 128;
        return ByteCache.cache[(int)b + offset];
    }
 
 
    //short原生类型自动装箱成Short
    public static Short valueOf(short s) {
        final int offset = 128;
        int sAsInt = s;
        if (sAsInt >= -128 && sAsInt <= 127) { // must cache
            return ShortCache.cache[sAsInt + offset];
        }
        return new Short(s);
    }
 
    //char原生类型自动装箱成Character
    public static Character valueOf(char c) {
        if (c <= 127) { // must cache
            return CharacterCache.cache[(int)c];
        }
        return new Character(c);
    }
 
    //int原生类型自动装箱成Integer
    public static Integer valueOf(int i) {
        if(i >= -128 && i <= IntegerCache.high)
            return IntegerCache.cache[i + 128];
        else
           return new Integer(i);
    }
 
    //long原生类型自动装箱成Long
    public static Long valueOf(long l) {
        final int offset = 128;
        if (l >= -128 && l <= 127) { // will cache
            return LongCache.cache[(int)l + offset];
        }
        return new Long(l);
    }
 
    //double原生类型自动装箱成Double
    public static Double valueOf(double d) {
        return new Double(d);
    }
 
 
    //float原生类型自动装箱成Float
    public static Float valueOf(float f) {
        return new Float(f);
    }

Test:

//Test
public class Main{
    public static void main(Strign[] args){
        Integer i1=100;
        Integer i2=100;
        Integer i3=200;
        Integer i4=200;
        System.out.println(i1==i2);//true
        System.out.println(i3==i4);//false
    }
}
//是因为valueOf的具体实现,在创建对象时,数值在[-128,127]之间会返回之前创建过的对象。

(3)需要注意的是“+”等运算符对包装类对象不适用,所以会自动拆箱为基本数据类型后再运算
并且new +包装类 创建对象时一定会新建一个对象,不会调用已存在的对象。

public class Main{
    public static void main(Strign[] args){
        Integer i1 = 40; 
        Integer i2 = 40; 
        Integer i3 = 0; 
        Integer i4 = new Integer(40); 
        Integer i5 = new Integer(40); 
        Integer i6 = new Integer(0); 
        System.out.println("i1=i2 " + (i1 == i2)); //true
        System.out.println("i1=i2+i3 " + (i1 == i2 + i3)); //true
        System.out.println("i1=i4 " + (i1 == i4)); //false
        System.out.println("i4=i5 " + (i4 == i5)); //false
        System.out.println("i4=i5+i6 " + (i4 == i5 + i6)); //true
        System.out.println("40=i5+i6 " + (40 == i5 + i6)); //true
    }
}
//i4 == i5 + i6语句为true,是因为”+“对包装类不适用,要先对i5,i6拆箱再运算,变为i4==40;由于Integer对象无法与数值比较,所以再对i4拆箱,变为40==40,结果为true。

更详细解答请前往深入刨析Java中的装箱与拆箱

  1. 引用数据类型:数组、类、接口
    Lambda表达式允许通过表达式来代替功能接口,所以可以看作为引用数据类型。Lambda表达式是Java 8中一个重要的新特性,lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体。

  2. 基本数据类型之间的转换:
    (1)自动类型转换:不需要书写代码,由系统自动完成的类型转换。
    规则一:byte—>char、short —> int —> long —> float —> double;
    规则二:当把任何基本数据类型的值和字符串值(String)进行连接运算时(+),基本数据类型会自动转换为字符串型。
    (2)强制类型转换:必须书写代码才能完成的类型转换。该类类型转换很可能存在精度的损失,所以必须书写相应的代码,并且能够忍受该种损失时才进行该类型的转换。当存在这个方向(double→float→long→int→short(char)→byte)的转换时,则必须使用代码进行强制转换

//自动类型转换:
System.out.println(‘a’+1+”hello!)//结果:98hello! ;因为char型(‘a’)先转换为int型,变为97;再与1进行运算,变为98;接着遇到字符串转换为字符串型,输出98hello!

//强制类型转换:
double  d  =  3.10;
int  n  =  (int)d;

泛型

Java泛型是jdk5引入的新特性,提供了编译时类型安全检测机制。就是将类型由原来的具体的类型参数化(类似于方法中的变量参数),此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。
Java泛型只在编译期有效,泛型信息不会进入到运行时阶段。即泛型只会在编译时帮助判断Java语言使用正确性,而本质上都属于同一个类型,在逻辑上看以看成是多个不同的类型,实际上都是相同的基本类型。(类型擦除)

import java.util.ArrayList;
    public class Test {
        public static void main(String []args) {
            ArrayList<String> a = new ArrayList<String>();  //创建泛型
            ArrayList b = new ArrayList();  
            Class c1 = a.getClass();  //获取泛型的类型
            Class c2 = b.getClass();  
            System.out.println(c1 == c2); //输出true
        }
    }

Java的泛型是伪泛型,在编译期间所有的泛型信息就会被擦除掉;例如定义List<Object>List<String>,在编译后都变成List,JVM看到的只是List,附加信息看不到。也是Java泛型的实现方法:类型擦除,类型擦除后保留原始类型。
详细类型擦除解答:Java泛型类型擦除及类型擦除带来的问题

注意:
(1)泛型类型变量不能是基本数据类型,可以是基本数据类型的包装类或引用数据类型或自定义类型。
(2)不能对确切的泛型类型使用instanceof操作。

if(ex_num instanceof Generic<Number>){ }//编译会报错

泛型的使用:
(1)泛型类:

//此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型
//在实例化泛型类时,必须指定T的具体类型
public class Generic<T>{ 
    //key这个成员变量的类型为T,T的类型由外部指定  
    private T key;

    public Generic(T key) { //泛型构造方法形参key的类型也为T,T的类型由外部指定
        this.key = key;
    }

    public T getKey(){ //泛型方法getKey的返回值类型为T,T的类型由外部指定
        return key;
    }
}

如何实例化:

//传入的实参类型需与泛型的类型参数类型相同,即为Integer.
Generic<Integer> genericInteger = new Generic<Integer>(123456);

//传入的实参类型需与泛型的类型参数类型相同,即为String.
Generic<String> genericString = new Generic<String>("key_vlaue");

.
(2)泛型接口:

//定义一个泛型接口
public interface Generator<T> {
    public T next();
}

//实现泛型接口,不指定类型
class GeneratorImpl<T> implements Generator<T>{
    @Override
    public T method(){
        return null;
    }
}

//实现泛型接口,指定类型
class GeneratorImpl<T> implements Generator<String>{
    @Override
    public String method(){
        return "hello";
    }
}

.
(3)泛型方法:

public static <T> void show(T t){...}

.
(4)泛型的通配符:

  1. ?:表示不确定的Java类型
  2. T:表示具体的一个Java类型
  3. K V:表示Java键值中的Key和Value
  4. E:代表Element

上边界通配符(<? extends E>):List<? extends Animal>作为一个方法的形参时,实际操作类型只能使用Animal的子类和本身(List<Dog>List<Animal>
下边界通配符(<? super E>):List<? super Dog>作为一个方法的形参时,实际操作类型只能使用Dog的父类和本身(List<Animal>List<Dog>

参考的Java泛型中的通配符详解文章

常量和变量

  1. 常量:通常有字符串常量(双引号表示)、字符常量(点引号表示)、整数常量、浮点数常量、布尔常量(true/false)、空常量(null,需注意的是空常量不能直接打印)

    字符串常量和字符常量的区别:
    1.形式上:字符型常量:单引号引起;字符串常量:双引号引起。
    2.含义上:字符常量相当于一个整型值(ASCII值),可以参与表达式运算;字符串常量代表一个地址值,在内存中存放的位置。
    3.内存大小:字符常量:2字节;字符串常量:若干字节。

  2. 变量:可分为局部变量和成员变量
    成员变量和局部变量的区别:
    (1)语法形式上:成员变量是属于类的,在整个类都可以使用,局部变量是方法中定义的变量,只能在方法内部使用。成员变量可以被public、private、static等修饰符修饰,局部变量不可以,但两者都可以被final修饰。
    (2)存储方式上:局部变量存储在栈中;成员变量存储在堆中。
    (3)生命周期上:成员变量随着对象的创建而存在;局部变量随着方法的调用而自动消失
    (4)初值:成员变量如果没有赋值,会有默认值,自动以数据类型的默认值而赋值;局部变量不会自动赋值。
    在这里插入图片描述

命名方式:

1.包名:所有字母小写;xxxyyyzzz
2. 类名、接口名:所有单词的首字母大写;XxxYyyZzz
3. 变量名、方法名:第一个单词首字母小写,其他首字母大写;xxxYyyZzz
4. 常量名:所有字母都大写,单词之间用下划线 ;XXX_YYY_ZZZ
注意:命名时不可以使用关键字和保留字。

运算符

1.算术运算符(+、-、*、/、%、++、- -)
(1)自增、自减运算符(++、- -):放在操作数前,先运算再赋值;放在操作数之后,先赋值再运算。

2.关系运算符(==、!=、<、>、<=、>=):结果为Boolean型

3.赋值运算符(=)

4.逻辑运算符(&(与)、|(或)、!(非)、&&(与)、||(或))

5.位运算符:
m<<n:左移(m2en)
m>>n:右移(m
2e-n)
m>>>n:无符号右移:正数时与右移一致
m&n:与运算
m|n:或运算
m^n:异或运算
在这里插入图片描述
6.三目运算符(m>n?m:n;)

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值