zoukankan      html  css  js  c++  java
  • Java入门(三):变量和运算符

    上次谈到了Java的基本数据类型,今天接着聊Java的变量、运算符。

    一、变量

    1、变量的分类

    变量分为成员变量、局部变量和常量,其中成员变量又分为实例变量、类变量。

    2、变量的定义

    语法:变量类型(可以是基本类型,也可以是其他) 变量名 = 变量值 英文;结尾。

    2.1 可以单次声明一个变量,也可以单次声明多个变量。

    2.2 不能以数字、运算符、特殊字符(下划线、美元符号$除外)开头。

    2.3 下划线 _ 可以作为开头,但是不建议这样命名。

    2.4 可以使用中文命名,但是不建议这样做。

    2.5 不能使用现有Java关键字和保留字命名。

    2.6 建议使用驼峰命名法。

    类名的首字母大写;变量名、方法名首字母小写;包名全部小写;特殊含义的缩略词全部大写;常量名全部大写;多个单词可以使用下划线分割。做到见名知意,不要使用拼音字母缩写、拼音全拼、英文拼音混合的命名格式,不知道如何翻译请查字典或在线翻译单词。变量名长一点无所谓,命名合理、规范,见名知意就可以。

    3、变量的使用

    实例变量的使用,需要使用new关键字创建对象,再通过对象引用。静态变量可以直接使用。在使用变量前,请先初始化赋值,不能声明不赋值直接使用。

    package javalearningday02;
    
    /**
     * 变量的使用
     * @author 小川94
     * @date 2018年1月21日
     */
    public class UseVariable {
        
        // 成员变量,也可以称为全局变量,可在本类或者其他类中使用
        private int age = 18;
        
        // 声明一个静态常量,成员变量的一种,也是一个类变量
        private static final String GENDER = "BOY";
        
        // 常量,由关键字final定义
        private final String NAME = "小川94";
        
        public static void main(String[] args) {
            // 在main方法中定义的局部变量
            int anotherAge = 20;
            
            // 变量的定义
            int a; // 单个变量定义
            int b = 2; // 单个变量定义并初始化
            int c,d; // 单次定义多个变量
            int _num = 1; // 可以是下划线开头,但是不建议
            int num_ = 2; // 可以下划线结尾
            int $num; // 也可以美元符号开头
            int num2; // 可以是数字结尾
            //int +num; // 错误写法,不能用运算符开头
            //int .num; // 错误写法,不能用.号开头
            //int 2num; // 错误写法,不能以数字开头
            //int *num; // 错误写法,不能以*开头,其他特殊符号也是不可以的
            int 变量 = 2; // 可以使用中文,但是建议不要使用
            
            // 不能使用关键字命名
            //int class; // 不能使用关键字
            //int goto; // Java保留关键字(保留关键字是指那些现有Java版本还未使用的关键字,但还是关键字)
            //int const; // Java保留关键字
            
            // 不能使用保留字命名
            /*
            int true;
            int false;
            int null;*/
        }
        
        public static String askName(String name){
            // 局部变量只能在该变量定义并且初始化的操作域中使用,跨域使用会报错
            // 错误写法  anotherAge cannot be resolved to a variable
            //System.out.println(anotherAge);
            
            // 不能对非静态变量进行静态引用
            // 错误写法  cannot make a static reference to the non-static field age
            // System.out.println(age); 
            
            // 对于全局变量的引用,如果是非静态的,需要利用对象引用
            UseVariable useVariable = new UseVariable();
            System.out.println(useVariable.age);
            
            // 类变量(静态成员变量)可以直接使用
            System.out.println("小川94的性别是"+GENDER);
            return "Hello "+name;
        }
    }

    二、运算符

    知道了数据类型,知道如何声明一个变量并初始化,下面就开始做数据运算操作。

    1、赋值运算符。

    =(赋值),要和数学中的等号区分。

    2、算术运算符。

    +(加法)、-(减法)、*(乘法)、/(除法)、%(取余)。这五种是开发中比较常用的。

    关于除法:

    (1)如果被除数是0,运行则会报算术异常,在做除法时需要判断被除数是否为0。

    (2)如果是两个整数做除法,可能会丢失计算精度,选择合适的数据类型尤为重要。

    关于取余:

    (1)负数对整数的余数是负数和0。

    (2)正数的余数是有周期性变化的。

    (3)余数是有范围的数,可以控制数据范围。

    3、数值类型之间的转换

    数值之间的转换可以分为自动转换、强制转换两种形式。

    3.1 自动转换

    如果两个数中有一个为double类型,另一个数会被转为double类型,然后再进行运算。

    如果两个数中有一个为float类型,另一个数会被转为float类型,然后再进行运算。

    如果两个数中有一个为long类型,另一个数会被转为long类型,然后再进行运算。

    如果没有上述的三种的类型,两个数都会被转为int进行运算。

    小范围的数据类型可以自动转换到大范围数据类型,大范围的数可以涵盖小范围的数,小范围内的数可以映射到大范围内的数。

    3.2 强制类型转换

    从大范围的数向小范围的数转换,称之为强制转换,用法是在目标数据前使用括号,将想要转换的类型输入括号即可。

    关于强制转换,有几点需要注意:

    (1)范围内的数,转换是没有损失的。

    (2)double转换为float,会出现精度损失。

    (3)浮点数转换为整数,只会保留原数的整数位,不会保留小数位,也不会进行四舍五入操作。

    (4)范围外的数,会有溢出的风险。

    4、结合赋值和运算符

    有时候为了省事,会把算术运算符和赋值运算符连着一起写。如:int n += 4; 这一句和int n = n+4;是等价的,其他的算术运算符也是如此,可以单独写在赋值符号的前面。

    5、自增、自减运算符

    自增的语法是 变量++; 自减的语法是 变量--; 作用是将变量的值增加1,注意是变量,不是整体。

    先加加(++变量)和后加加(变量++)在运算时有很大的不同。

    (1)先加加,这里为了方便简写为++n吧,是先将n的值加1,然后取n的值作为表达式(++n)整体的值。

    int b = ++a;

    -->第一步 a = a+1;

    -->第二步 b = a;

    (2)后加加,同样为了方便简写为n++;是先将n的值作为表达式(n++)整体的值,然后将n的值加1。

    int b = a++;

    -->第一步 b = a;

    -->第二步 a = a+1;

        /**
         * 后加加,先将变量值赋给整体表达式,再计算n+1。后减减同理。
         */
        public static void selfAddAfter() {
            int n = 5;
            n = n++;
            n = n++;
            n = n++;
            n = n++;
            System.out.println("n的值是"+n); // n = 5;
        }
        
        /**
         * 先加加,先将变量值加1,再将加过1后的值赋给整体表达式。先减减同理
         */
        public static void selfAddBefore() {
            int m = 5;
            int n = ++m;
            System.out.println("m的值是"+m); // m = 6;
            System.out.println("n的值是"+n); // n = 6;
        }

    6、关系运算符

    关系运算符,也可以称为比较运算符,包括>(大于)、<(小于)、>=(大于等于)、<=(小于等于)、==(等于)、!=(不等于),比较的结果为true或false。

    7、逻辑运算符

    逻辑运算符,包含&&(逻辑与运算)、||(逻辑或运算)、!(逻辑非运算)

    在进行逻辑运算时,会出现短路运算的情况,即前一个逻辑判断已经可以为结果定性,后面的逻辑判断是不会执行的。

        /**
         * 逻辑运算符
         */
        public static void logicOperation() {
            // false,并且发生了短路运算,因为3>4为false,可以直接为整个表达式定性,无需再判断4>5表达式的值
            // 与运算中,所有条件都为true时,整体表达式才为true
            System.out.println(3>4 && 4>5); // 4>5下面标黄了,提示是Dead code,说明不会运行后半部分的表达式
            
            // true,这里也发生了短路运算,不会去判断3>4的值
            System.out.println(2>1 || 3>4);
            // 或运算中,只要有一个为true,整个表达式的值就是true
            System.out.println(3>4 || 2>1);
            
            // true,非运算中,true变false,false变true
            System.out.println(!(4>5));
        }

    8、位运算符

    与(&)、非(~)、或(|)、异或(^)、<<(带符号左移)、>>(带符号右移)、>>>(无符号右移),下面将详细介绍这七种运算符。

    8.1 与(&)运算

        /** 
         * 与(&)运算
         * 规则:先将要运算的数转为二进制,当相同的位上均为1时结果为1,否则结果为0
         */
        public static void andOperation() {
            /**
             * 98的原码: 00000000 00000000 0000000 01100010
             * 18的原码: 00000000 00000000 0000000 00010010
             * 与运算后:  00000000 00000000 0000000 00000010
             * 转换为十进制的数是2
             */
            int num = 98&18;
            System.out.println("(98&18)的与(&)运算结果:"+num); // num = 2
        }

    8.2 非(~)运算

        /** 
         * 非(~)运算
         * 规则: 正数的非运算是先取反再计算补码,负数的非运算是先计算补码再取反
         */
        public static void nonOperation() {
            byte num = ~90;
            /**
             * 正数非运算:原码 -->取反(1变0,0变1,非运算)-->反码(符号位不变,其余1变0,0变1)--->补码(反码的基础上加1)
             *      90
             * 原码: 00000000 00000000 00000000 01011010
             * 取反: 11111111 11111111 11111111 10100101
             * 反码: 10000000 00000000 00000000 01011010
             * 补码: 10000000 00000000 00000000 01011011
             * 转为十进制数则是-91
             */
            System.out.println("90的非(~)运算结果:"+num); // num = -91
            
            /**
             *      10
             * 原码: 00000000 00000000 00000000 00001010
             * 取反: 11111111 11111111 11111111 11110101
             * 反码: 10000000 00000000 00000000 00001010
             * 补码: 10000000 00000000 00000000 00001011
             * 转为十进制数是-11
             */
            System.out.println("10的非(~)运算结果:"+(~10)); // -11
            
            /**
             * 负数非运算:原码 --->反码(符号位不变,其余1变0,0变1)--->补码(反码的基础上加1)--->取反(1变0,0变1,非运算)
             *       -5
             * 原码: 10000000 00000000 00000000 00000101
             * 反码: 11111111 11111111 11111111 11111010
             * 补码: 11111111 11111111 11111111 11111011
             * 取反: 00000000 00000000 00000000 00000100
             * 转为十进制为 4 
             */
            System.out.println("(-5)的非(~)运算结果:"+(~(-5))); // 4
        }

    8.3 或(|)运算

        /** 
         * 或(|)运算
         * 规则:当两边操作数的位有一边为1时,结果为1,否则为0。
         */
        public static void orOperation() {
            /**
             * 23的原码: 00000000 00000000 00000000 00010111
             * 75的原码: 00000000 00000000 00000000 01001011
             * 或运算:   00000000 00000000 00000000 01011111
             * 转换为十进制数是95
             */
            System.out.println("(23|75)的或(|)运算结果"+(23|75)); // 95
        }

    8.4 异或(^)运算

        /**
         * 异或(^)运算
         * 规则:两边的对应位不同时,取1,否则取0。如果遇到负数,需要用负数的补码进行计算
         */
        public static void differentOr() {
            /**
             * 17的原码: 00000000 00000000 00000000 00010001
             * 29的原码: 00000000 00000000 00000000 00011101
             * 异或运算:  00000000 00000000 00000000 00001100 
             * 转为十进制数是12
             */
            System.out.println("(17^29)的异或(^)运算结果:"+(17^29)); //12
            
            /**
             * -17的原码: 10000000 00000000 00000000 00010001
             * -17的反码: 11111111 11111111 11111111 11101110
             * -17的补码: 11111111 11111111 11111111 11101111
             *  29的补码: 00000000 00000000 00000000 00011101
             *  运算结果:  11111111 11111111 11111111 11110010
             *  对结果反码: 10000000 00000000 00000000 00001101 
             *  对结果补码: 10000000 00000000 00000000 00001110
             *  结果转为十进制数是-14
             */
            System.out.println("(-17^29)的异或(^)运算结果:"+(-17^29)); //-14
        }

    8.5 带符号左移(<<)运算

        /**
         * 带符号左移(<<)运算
         * 规则: 符号位不变,左移几位,则在补码(正数的补码、反码与原码一样)的后面补几个0
         *      也可以简单理解成数学运算,左移几位,就是原数乘以2的几次方
         */
        public static void withSymbolToLeft() {
            /**
             * 10的原码: 00000000 00000000 00000000 00001010
             * 左移四位:  00000000 00000000 00000000 10100000
             * 转换为十进制数是160
             * 也可以理解成数学运算中的  10*(2*2*2*2) = 10*16 = 160
             */
            System.out.println("(10<<4)带符号左移(<<)运算的结果:"+(10<<4)); // 160
            /**
             * -9的原码: 10000000 00000000 00000000 00001001
             * -9的反码: 11111111 11111111 11111111 11110110
             * -9的补码: 11111111 11111111 11111111 11110111
             * 左移4位:  11111111 11111111 11111111 01110000
             * 再反码:   10000000 00000000 00000000 10001111
             * 再补码:   10000000 00000000 00000000 10010000
             * 转为十进制数是-144
             * 也可以理解成数学运算中的  (-9)*(2*2*2*2) = (-9)*16 = -144
             */
            System.out.println("(-9)<<4)带符号左移(<<)运算的结果:"+((-9)<<4)); // -144
        }

    8.6 带符号右移(>>)运算

        /**
         * 带符号右移(>>)运算
         * 规则: 正数右移时,右移几位,在补码的左边加几个0,右边的被自动挤掉;
         *      负数右移时,右移几位,在补码的左边加几个1,右边的被自动挤掉
         */
        public static void withSymbolToRight() {
            /**
             * 20的原码: 00000000 00000000 00000000 00010100
             * 右移4位:  00000000 00000000 00000000 00000001
             * 转为十进制数是1
             */
            System.out.println("(20>>4)带符号右移(>>)运算结果:"+(20>>4));
            /**
             * -86的原码: 10000000 00000000 00000000 01010110
             * -86的反码: 11111111 11111111 11111111 10101001
             * -86的补码: 11111111 11111111 11111111 10101010
             * 右移四位:   11111111 11111111 11111111 11111010
             * 再计算反码:  10000000 00000000 00000000 00000101
             * 再计算补码:  10000000 00000000 00000000 00000110
             * 转为十进制数是-6
             */
            System.out.println("(-86)>>4带符号右移(>>)运算结果:"+((-86)>>4)); // -6
        }

    8.7 无符号右移(>>>)运算

        /**
         * 无符号右移(>>>)运算
         * 规则: 无论正数还是负数,右移几位,则在其补码左边加上几个0
         */
        public static void noSymbolToRight() {
            /**
             * 50的原码: 00000000 00000000 00000000 00110010
             * 右移4位:  00000000 00000000 00000000 00000011
             * 转为十进制数是3
             */
            System.out.println("(50>>>4)的无符号右移(>>>)运算结果:"+(50>>>4)); // 3
            /**
             * -28的原码: 10000000 00000000 00000000 00011100
             * -28的反码: 11111111 11111111 11111111 11100011
             * -28的补码: 11111111 11111111 11111111 11100100
             * 右移四位:   00001111 11111111 11111111 11111110
             * 再转为十进制数是  0+0+0+0+134217728+67108864+33554432+16777216
             *                +8388608+4194304+2097152+1048576+524288+262144+131072+65536
             *             +32768+16384+8192+4096+2048+1024+512+256
             *             +128+64+32+16+8+4+2+0 = 268435454
             */
            System.out.println("(-28)>>>4的无符号右移(>>>)运算结果:"+((-28)>>>4)); // 268435454
        }

    9 三目运算符

    语法为 条件 ? 条件为true执行 : 条件为false执行 。可以单个写,也可以多层嵌套,但是如果条件比较复杂,建议单独抽出来处理,便于阅读和维护。

        public static void threeHeadOperation() {
            int n = 3;
            int m = 10;
            int maxNum = n>m ? n : m; //单个写法
            System.out.println(maxNum); // maxNum = 10
            
            // 设定忽略num小于0的情况
            int num = 4;
            String str = num != 0 ? num%2 == 0 ? "是偶数" : "是奇数" : "是0";
            System.out.println(str); // 是偶数
            
            // 上面的三目运算符等价于下面的代码
            if (num != 0) {
                if (num%2 == 0) {
                    System.out.println("num是偶数");
                } else {
                    System.out.println("num是奇数");
                }
            } else {
                System.out.println("num是0");
            }
        }

    10 instanceof

    public class JavaOperation {
    
        public static void main(String[] args) {
            instanceOfOperation();
        }

    /** * instanceof 是用来在运行时指出对象是否是特定类的一个实例 */ public static void instanceOfOperation() { A a = new A(); String str = a instanceof A ? "a是A的实例" : "a不是A的实例"; System.out.println(str); // a是A的实例 String str2 = null instanceof A ? "null是A的实例" : "null不是A的实例"; System.out.println(str2); // null不是A的实例 } } class A{ }

    Java入门(三)源码已经上传Github,地址:https://github.com/XiaoChuan94/javalearning/tree/master/javalearningday02,可以参考。

    文章首发于我的个人公众号:悦乐书。喜欢分享一路上听过的歌,看过的电影,读过的书,敲过的代码,深夜的沉思。期待你的关注!

    公众号后台输入关键字“Java学习电子书”,即可获得12本Java学习相关的电子书资源,如果经济能力允许,还请支持图书作者的纸质正版书籍,创作不易。

  • 相关阅读:
    Python Django框架笔记(三):django工作方式简单说明和创建用户界面
    Python Django框架笔记(二):创建应用和django 管理
    Python笔记(十三):urllib模块
    Python Django框架笔记(一):安装及创建项目
    Python笔记(十二):操作数据库
    Python笔记(十一):多线程
    Python网络爬虫笔记(五):下载、分析京东P20销售数据
    Python笔记(十):正则表达式
    Python网络爬虫笔记(四):使用selenium获取动态加载的内容
    【React Native】Execution failed for task ':app:installDebug'. > com.android.builder.testing.api.DeviceException: No online devices found.
  • 原文地址:https://www.cnblogs.com/xiaochuan94/p/8333952.html
Copyright © 2011-2022 走看看