zoukankan      html  css  js  c++  java
  • java入门(2)--数据类型

    类型系统

    高级语言都有自己的类型系统。

    类型系统可以划分为:强类型,弱类型

    或者:静态类型,动态类型。

    通俗地说,强类型就是语言比较在意不同类型的区别,会对某个类型所能作的动作进行严格审查,

    而弱类型就睁一眼闭一眼,想做什么就做什么,比如c是弱类型,你本来定义了一个int,待会儿可以拿它当double来用,虽然c语言也会抱怨一下,但绝不阻止你。

    (她的意思是,你一定要玩火,那就好自为之吧,我管不了)

    如果是在编译期间进行这样的检查,就是静态类型。运行时才检查就是动态类型。

    java是强类型的,静态类型的。

    也就是说,java中很受限制,你定义了某个类型,那就一定按该类型的约束来行事,不能开后门。

    如果你想仿照c那样,来点小小的变换技巧什么的,都不用等到运行,java的编译器直接把你毙掉。因为她是静态类型的。

    类型系统提供了安全保障,无视类型也能带来灵活性,这取决于你的需求。

    比方说,洗衣机能放入什么?当然是衣服了!

    被单行不行? 可以。

    袜子行不行?可以。

    苹果行不行?不行!

    如果是c语言,对话是这样的:

    你:把苹果放入洗衣机!

    c:恐怕不好吧。

    你:少废话,让你放就放。

    c:那就放了,出什么事你自己负责,别说我不提醒你。

    如果是java,对话很简单:

    你:把苹果放入洗衣机!

    java:办不到!

    但编译器必定是傻乎乎的,你可以哄骗它。

    你:把苹果放入洗衣机!

    java:办不到!

    你:把苹果当“物品”看,记为x

    java: 没问题

    你:现在x是物品了,把它放入洗衣机。

    java: 这不行啊,只有“被服”类型的才能放入。

    你:那先把 x 转为需要的类型,再放入。

    java: 这不好吧,你肯定x是"被服"吗?

    你:我肯定,放吧

    java: 好吧。

    看到了?我们可以说服编译器做一些危险的事。但最好别这样。

    编译器是来帮我们防止逻辑错误的,你这样狠心地骗它太残忍了。。。。

    所以说,类型还是有用的。

    java 的类型系统可以分为两个大类:基本类型和复合类型。

    基本类型又叫:简单类型或原生类型。包含:整数,浮点数,字符,布尔型四大类。

    而复合类型也叫复杂类型,涉及:类,接口,数组。

    我们先从最简单的类型说起。

    整型

    为了适应不同的场合,java中的整型有4种: byte short int long

    它们表示的数的大小范围不同。如果没有特殊的用途,用 int 就好了。这是 4 个字节的类型,可以表示大约20亿左右的有符号的整数。

    我们可以在整型上进行 + - * / 和取模(%)运算

    例一:

    已知一个数字的百位,十位,个位,求这个数字。

    public class A
    {
        public static void main(String[] args){
            int a = 5;
            int b = 6;
            int c = 9;
            
            int n = a * 100 + b * 10 + c;
            System.out.println(n);
        }
    }

    这会输出: 569

    例二:

    已知一个整数,分别输出它的百位,十位,个位。

     1 public class A1
     2 {
     3     public static void main(String[] args){
     4         int n = 2736;
     5         int a = n % 1000 / 100;
     6         int b = n % 100 / 10;
     7         int c = n % 10;
     8         
     9         System.out.println(a);
    10         System.out.println(b);
    11         System.out.println(c);
    12     }
    13 }

    这会输出:7,3 和 6

    println 输出一项后会回车换行。如果不想换行,可以用 print 代替。

    也可以先把若干信息拼成一个大串,再输出这个串。

    String s = a + "," + b + "," + c;

    System.out.println(s);

    通过这样的代码来取出各个位,并不会去影响 n 的数值。

    如果用一下面的方法,会影响 n 的值。

     1 public class A2
     2 {
     3     public static void main(String[] args){
     4         int n = 2736;
     5         int c = n % 10; n = n / 10;
     6         int b = n % 10; n /= 10;
     7         int a = n % 10;
     8         System.out.println(a);
     9         System.out.println(b);
    10         System.out.println(c);
    11     }
    12 }

    一般情况下,我们都是每一行代码一个分号。然而也可以在一行放多条语句。

    n % 10 会取出n的最末位来。

    n / 10 会求出 n 除以 10 的商来,它的结果还是整数,不会得出类似273.6 的结果来。

    n /= 10 与 n = n / 10 的含义是一样的,不过这样写更酷一些。

    很多运算符都可以有对应的反身运算,表示对一个变量本身做的某个动作。

    n = n 运算 a, 一般都能写成:

    n 运算= a;

    n *= 100;

    就是把 n 乘以 100,再放回到 n 中。

    注意,这里的 *= 是一个整体,是一个运算符,中间不能有空格。 

    浮点数

    浮点类型常用的是 double(8位64bit), 必要的时候当然也可以用float(4位32bit)

    浮点数与其它类型的数字的运算结果还是浮点数。

    所以可能自动把一个整数数转为浮点数。

    double a = 10;  //正确

    System.out.println(10/3);   //结果是整数

    System.out.println(10/3.0);  //结果是浮点数

    浮点数可以被强制转为整数,这样会丢失它的小数部分。

    以下代码分别取得一个浮点数的整数部分和小数部分。

     1 public class A3
     2 {
     3     public static void main(String[] args){
     4         double x = 5.81236;
     5         int a = (int)x;
     6         double b = x - a;
     7         System.out.println(a);
     8         System.out.println(b);        
     9     }
    10 }

    浮点数因为是用有限的空间来存储的,所以存在一个表示精度的问题。

    在任何时候都要避免对两个浮点数进行相等性比较。

    不信的话,请执行如下代码:

    System.out.println(0.1+0.2 == 0.3);

    这会输出 false。

    但可以这样表达:

    System.out.println(Math.abs(0.1+0.2-0.3) < 1e-6);

    这意思是说:01+0.2的值与0.3相差不足10的负6次方。就是几乎相等的意思。

    这里的1e-6 是科学记数表示法。

    java提供了许多数学函数,比如:sin, log 等方便我们运算,都在Math对象中,是静态方法。

    System.out.println(Math.sin(30 * Math.PI/180));  //单位度需要转为弧度。

    浮点数的输出一般要求保留到小数后的多少位。

    有很多方法,比如,可以通过String 类的format方法,类似于c语言的 printf

     这里的需求其实是2种:

    一是不希望改变那个浮点数的真实值,只是在显示的时候,不要显示那么啰嗦冗长的小数,希望简短点而已。

    这代表了绝大多数的需求,正是用String.format的时机。

    1 public class A4
    2 {
    3     public static void main(String[] args){
    4         double a = Math.sin(0.2);
    5         System.out.println(a);
    6         System.out.println(String.format("%.3f",a));
    7     }
    8 }

    结果为:

    二是需要真实地修改那个浮点数,丢弃多余的小数部分。比如,银行存折上的余额计入利息后,只能四合五入到分,不能有更多的小数。

    这时,我们只需要一个小技巧,你自己研究一下吧。

    double a = Math.sin(0.15);
    System.out.println(a);
    double b = (int)(a * 100 + 0.5)/100.0;
    System.out.println(b);

    字符类型

    java中的字符类型存储的是它的unicode码。每个字符用了2个字节,这点与c语言是不同的。

    既然是unicode码,那它与整数就有天然的关系。

    字符类型可以直接赋值给整数,整数也可以赋值给字符类型(不过需要一个强制转换)

    char x = 'A';
    System.out.println(x);
    int n = x;
    System.out.println(n);
    System.out.println((char)97);

    字符如果是一个十进制的数码,可以把它转换为对应的真值,这个技巧十分常用。

    char x = '5';
    int k = x - '0';
    System.out.println(k);

    这是因为十进制的数码字符,它们的unicode码是连续的,并且是有规律的。

    布尔型

    布尔型表示是否的概念,只有两个值:true和false

    布尔值一般作为循环和分支的判断条件。

    有些运算会产生出布尔值。

    boolean x = 5 >= 3;
    boolean y = 1+2==3;
    boolean z = "abcd".equals("ABCD");

    布尔值本身也会通过逻辑运算符产生出新的布尔值。

    && 逻辑与

    || 逻辑或

    ! 逻辑非

    逻辑运算符具有一个十分重要的特性---短路求值。

    if(x>0 && f(x)==5) ....

    这句话在 x<=0 的情况下, f(x) 是不会去执行的。

    因为,x>0 是 false, 而 false && 任何东西都是false,那么表达式的值就一定是false,也就没有必要再计算下去了。

    字符串

    字符串并非是基本类型,它属于java的面向对象体系。

    String 是类名,new String() 创建出字符串对象。

    "abc" 是字符串常量。

    String s = "abc";

    这里的 s 并不是字符串本身,它是指向字符串的引用,相当于c语言中的指针。

    所以,如果:

    String s2 = s;

    这时,并非有两个字符串,而是有两个引用指向了同一个字符串。

    字符串是不可变的对象,也就是说,字符串一旦形成,它的内容不可更改!

    但,我们可以生生成新的字符串,并把旧的字符串丢弃。

    例如:

    String s = "abc";
    s = s + "de";
    System.out.println(s);

    这里,s开始的时候指向了字符串对象,内容是"abc",后来,把 "abc" 与 "de"进行了拼接操作,生成了新的字符串对象 "abcde"。

    然后,s 引用放弃了先前的对象,指向了新生成的对象,内容是:"abcde"

    字符串类型与字符类型的关系当然最为密切。

    因为字符串正是由字符构成的。

    字符串类中提供了丰富的方法,可以对串进行各种常见的操作。

    String s = "123456";
    int n = s.length();
    char x = s.charAt(n-1);

    如此操作,则 n 中存储了字符串的长度,

    x 中存储了最后一个字符,即:'6'

    String s1 = s.substring(0,3);
    String s2 = s.substring(3);

    s1 指向了新串,它是 s 的一个子串,内容: "123"

    substring方法的两个参数是:开始位置的下标,结束位置的下标。

    这里要注意,规则是:包含开始,不包含结束。

    我们也可以判断一个串是否包含某个子串:

    int k = s.indexOf("34");

    这会返回子串 "34" 在母串中的第一次出现的位置。

    如果找不到,就会返回-1。

    字符串可能是我们最常用的复合类型了,它还有一个很有趣的特性:

    任何类型都可以和一个串做加法,其动作就是和那个串拼接起来。

    String s = "" + 1 + 2 + (5>3) + 'A';
    System.out.println(s);
  • 相关阅读:
    iOS
    UI基本视图控制
    堆和栈的区别 ?
    单例模式
    Object-c的类可以多重继承么?可以实现多个接口么?Category是什么?重写一个类的方式用继承好还是分类好?为什么?
    id
    协议
    分类(类别)
    #import和#include以及@class三者的区别?
    内存管理
  • 原文地址:https://www.cnblogs.com/gyhang/p/8675237.html
Copyright © 2011-2022 走看看