七海的java学习笔记(十)

时间:2022-05-28 12:32:47

第十章 数字与静态

        静态方法与非静态方法的区别

                Java是面向对象的,但若处于某种特殊情况下,通常是使用方法,则不需要类的实例。static这个关键字可以标记出不需要类实例的方法。一个静态的方法代表说“一种不依靠实例变量也就不需要对象的行为”。

                当成员被静态修饰后,就多了一种调用方式,除了可以被对象调用外,还可以直接被类名调用。语法:类名.静态成员。

Math.random();  //直接用类名调用

                static特点:1. 随着类的加载而加载,随着类的消失而消失(说明生命周期最长)

                                  2. 优先于对象存在(静态先存在,对象后存在)

                                  3. 被所有对象所共享

                                  4. 可以直接被类名所调用

                静态的使用注意事项:1. 静态方法只能访问静态成员,因为非静态成员是对象创建后才存在的,而静态成员是优先                                                          于对象存在的。

                                                  2. 静态方法中不可以定义this、super等关键字,因为静态优先于对象存在,静态优先于对象                                                        存在,静态优先于对象存在。

                静态的使用有利有弊:静态是对对象的共享数据进行单独空间的存储,节省空间。还可以被类名直接调用;但是对象的生命周期过长,因为与对象共生共存。而且静态只能访问静态。

                主函数main()也是静态的。

               

        final(最终)

                final也是一个修饰符,可以修饰类、函数、变量。
                被final修饰的类不可以被继承,避免被继承后被子类复写功能。
                被final修饰的方法不可以被覆盖。
                被final修饰的变量是一个常量,只能赋值一次,既可以修饰成员变量,又可以修饰局部变量。
                静态的final变量是常数。一个被标记为final的变量代表它一旦被初始化后就不会改动。也就是说类加载之后静态final变量就会一直维持原值,比如圆周率:
public static final double PI = 3.1415926;
                此变量被标记为public,因此可供各方读取。
                此变量被标记为static,所以你不需要类的实例。
                此变量被标记为final,因为圆周率是不变的。
                此外没有别的方法可以识别变量为不变的常数,但有些命名惯例可以帮你认出来。
                常量的名称应该都是大写字母。

       

        Math方法

                来看一下Math类,这是一个数学类,里面有很多可以进行计算的方法,它们都是静态的,所以我们可以直接用类名来调用。      

Math.random()
//返回介于0.0~1.0之间的双精度浮点数,比如想获取1-5之间的随机整数可以这样做
int r = (int)(Math.random()*5);

Math.abs()
//返回双精度浮点数类型参数的绝对值。这个方法有覆盖版本,因此传入整型会返回整型,传入双精度浮点数就会返回双精度浮点数

Math.round()
//根据参数是浮点型或双精度浮点数返回四舍五入之后的整型或长整型值。
int x = Math.round(-24.8f); //返回-25
int y = Math.round(24.45f); //返回24

Math.min();
//返回两参数中较小的那一个。这有int、long、float或double的覆盖版本
int x = Math.min(24,240); 返回24

Math.max();
//返回两参数中较大的那一个。也有int、long、float和double的重载版本
int x = Math.max(24,240); //返回240

                当然还有更多的方法,具体请自行查阅API。


        数字的格式化

                在Java中,数字与日期的格式化功能并没有结合在输出/输入功能上。通常对用户显示数字是通过GUI来进行的。你会把String放在可滚动的文字区域块或表格中。如果格式化功能只有绑在文字模式输出的命令上,那就没有办法把字符串以比较漂亮的格式输出到GUI上。
                从Java5.0开始,更多更好更有扩展性的功能是通过java.util中的Formatter这个类来提供的。但你无需自己创建与调用这个class上的方法,因为java5.0已经把便利性的功能加到部分的输入输出类和String上,因此只要调用静态的String.format()并传入值与格式设定就好。
                当然还是得知道如何提供格式设定,下面会有一些示例。
//将数字以带逗号的形式格式化
String s = String.format("%,d",1000000000);
System.out.println(s);
//打印结果为 1,000,000,000
                解析上面格式化的结构。
                基本上来说,格式化由两个主要部分组成(不只是这样,但我们先从简单的开始)。
                1. 格式指令:描述要输出的特殊格式。
                2. 要格式化的值:不是所有东西都能被格式化。例如,如果你的格式指令适用于浮点数,则你就不能传入Dog或看                                                起来很像浮点数的String。

                %符号代表把参数放在这里。format()方法的第一个参数被称为格式化串,它可以带有实际上就是要这么输出而不用转译的字符。当你看到符号%时,要把它想做是会被方法其余参数替换掉的位置。
format("I have %.2f bugs to fix",476578.09876);
//输出结果为 I have 476578.10 bugs to fix
                此例的%符号是第二个参数会放置的位置,“.2f”代表该参数要使用的格式,其他的字都会以原来的方式输出。

        格式化说明的格式

                 跟在百分号后面包括类型指示(像是d或f)的每个东西都是格式化的指令。除非遇到新的百分号,在类型指示之后的一组字符,格式化程序会假设都是直接输出的字符串。
                格式化说明最多会有五个部分(不包括%符号)。下面的[]符号里面都是选择性的项目,因此只有%与type是必要的。格式化说明的顺序是有规定的,必须要以这个顺序来指定。
%[argument number][flags][width][.precision]type
                 依次分析上面的格式:
                                1. [argument number] : 如果要格式化的参数超过一个以上,我们可以在这里指定是哪一个
                                2. [flags] : 特定类型的特定选项,例如数字要加逗号或正负号
                                3. [width] : 最小的字符数,注意,这不是总数:输出可以超过此宽度,若不足则会主动补零
                                4. [.precision] : 精确度,注意前面有个圆点符号
                                5. type : 一定要指定的类型标识
format("%,6.1f",42.000);
//除了[argument number]之外其他的项目都用到了

         唯一必填项目是类型

                虽然类型是唯一必填的项目,但若指定别的项目,则类型必须是最后一项!类型修饰符有十几种(这不包括日期和时间的,它们有自己的一组),但大部分时间你会使用到%d或%f。且通常你会对%f加上精确度指示来设定所需要的小数长度。
//%d  decimal(十进制)
format("%d",42); //%d的参数必须能够与int相容。输出结果为42

//%f floating point(浮点)
format("%.3f",42.000000);//.3配上f会强制输出3位的小数,参数必须是浮点数类型,输出结果为42.000

//%x hexadecimal(十六进制)
format("%x",42);//参数必须是byte、short、int、long、BigInteger。输出结果为2a

//%c character(字符)
format("%c",42);//参数同上,但不包括BigInteger。输出结果为*,因为在ASCII中42代表"*"号
               超过一个以上参数是,会按顺序进行格式化,第二个参数会应用到第一个百分号上面,第二个参数会应用到第二个百分号上面,以此类推。
format("The rank is %,d out of %,.2f",one,two);


        时间的格式化

                
//完整的日期与时间:%tc
String.format("%tc",new Date());
//输出格式为 Sun Nov28 14:52:41 Mst 2004

//只有时间:%tr
String.format("%tr",new Date());
//输出格式为 03:01:47 PM

//周,月,日:%tA%tB%td
//因为没有刚好符合我们要求的输出格式,所以得组合三种形式来产生出所需要的格式:
Date today = new Date();
String.format("%tA %tB %td",today,today,today);
//这样就得把Data对象传进去三次,输出格式为 Sunday November 28

//同上,但不用从重复给参数
Date today = new Date();
String.format("%tA% <tB% <td",today);
//"<"这个符号是一个特殊的指示,用来告诉格式化程序重复利用之前用过的参数
                
                之前我们使用java.util.Date来查询今天的日趋,因此从这个类开始寻找适用的功能是很合理的,但当你检查API文件时,就会发现有很多Date的功能被停用了。但是这个类还是很适合用来取得目前的时间。
                我们可以使用 java.util.Calendar来操作日期。
                Calendar这个API的设计者打算要做全球化的思考。基本的想法是当你要操作日期时,你会要求一个Calendar,然后Java虚拟机会赏你一个Calendar的子类实例(实际上Calendar是一个抽象类,所以你能用到的是它具体的子类)。

                取得继承过Calendar的对象:你要如何取得抽象的Calendar的实例。
Calendar cal = new Calendar()
//这是无法通过编译的,要用下面的静态方法
Calendar cal = Calendar.getInstance();
                你无法取得Calendar的实例,但是你可以取得它的具体子类的实例。
                很明显,你不能取得Calendar的实例,因为Calendar是抽象的。但你还是能够不受限制的调用Calendar的静态方法,这是因为静态的方法是在类上而不是在某个特定的实例上。所以你对Calendar调用getInstance()会返回给你具体子类的实例。那是某种继承过Calendar(也就是Calendar的多态变化版本),并且会根据合约来相应Calendar应有的方法。

                Calendar类中的常用方法
add(int field,int amount) //加减时间值
get(int field) //取出指定字段的值
getInstance()  //返回Caledar,可指定地区
getTimeInMillis() //以毫秒返回时间
roll(int field,boolean up) //加减时间值,不进位
set(int field,int value) //设定指定字段的值
set(year,month,day,hour,minute) //设定完整的时间
setTimeInMillis(long millis) //以毫秒指定时间
//更多方法查阅API
               关键字段
DATE/DAY_OF_MONTH  //每月的几号
HOUR/HOUR_OF_DAY //小时
MILLISECOND //毫秒
MINUTE  //分钟
MONTH   //月份
YEAR    //年份
ZONE_OFFSET  //时区位移
//更多关键字段查阅API文档....