9.包和访问控制符
本章目标
- 包
- 修饰符
- 包装类
- 常用工具类
本章内容
如果在团队开发过程有,两个类都叫Date,那么我们该如何区分这两个类呢?
一、包
1、包的作用
包:就是一个文件夹。包结构对应计算机的目录结构
为了便于管理大型软件系统中数目众多的类,解决类命名冲突的问题,Java引入了(package)
公司初创期;技术部和销售部各有一位员工叫张三,财务怎么发工资?
2、包的规范
一般将公司域名反写作为包名
商业类型.公司名称.项目名称.业务模块.子模块
2.1、命名
- 必须是一个合法的标识符
- 必须全部小写
2.2、语句格式
package 包名;
-
包语句必须是源程序第一条语句
-
在package语句中,用
.
来指明包(目录)的层次。package com.woniuxy.hr;
3、导包
java中默认包为java.lang包,该包下的类在使用时无须导包,可以直接使用
当我们在程序中需要引用其它包的类时我们就使用import
句;
-
引入一个类
import java.io.File;
-
引入包中的所有类
import java.sql.*;
例如:我们在程序用引入java.sql包中的所有类
-
当前项目中,在同一包中的类可以互相引用,无需import语句,其它包需要导包
4、示例
package com.it.library.bean;
import java.util.Calendar;
/**
* 读者信息
*
* @author 张三
* @version 1.0
*/
public class Reader {
private String readerId;
private String readerName;
private String telephone;
private String address;
private Calendar joinDay;
……
}
二、修饰符
1、修饰符分类
1.1、访问修饰符
- public : 公共成员,完全公开,没有访问限制。
- private : 私有成员, 在类的内部才可以访问。
- protected : 保护成员,该包内部和继承类中可以访问。
- default(缺省):同一个包中
1.2、非访问修饰符
- final :用final修饰的类不能被继承,没有子类;用final修饰的方法不能被子类的方法覆盖;用final修饰的变量表示常量,只能被赋一次值。
- synchronized(加锁) : 是某个对象实例内,synchronized aMethod(){}可以防止多个线程同时访问这个对象的synchronized方法(如果一个对象有多个synchronized方法,只要一个线程访问了其中的一个synchronized方法,其它线程不能同时访问这个对象中任何一个synchronized方法)。
- native(本地): 使用native关键字说明这个方法是原生函数,也就是这个方法是用C/C++语言实现的,并且被编译成了DLL,由java去调用。这些函数的实现体在DLL中,JDK的源代码中并不包含,你应该是看不到的。对于不同的平台它们也是不同的。这也是java的底层机制,实际上java就是在不同的平台上调用不同的native方法实现对操作系统的访问的。java是跨平台的语言,既然是跨了平台,所付出的代价就是牺牲一些对底层的控制,而java要实现对底层的控制,就需要一些其他语言的帮助
2、类修饰符
2.1、类的访问修饰符
- public 所有其他类中均可引用
- default(不加访问控制符)
2.2、同一个包中的类可以引用类的非访问修饰符
- final
- abstract
3、方法的修饰符
3.1、方法的访问说明符
- public 所有其他类中均可调用
- protected 同一个包中的其他类或子类中可以调用
- default(不加访问控制符) 同一个包中的其他类可以调用
- private 只能在本类中调用
3.2、方法的其它修饰符
- static
- final
- abstract
- native
- synchronized
4、属性修饰符
4.1、属性的访问修饰符
- public
- protected
- default(不加访问说明符时)
- private属性的
4.2、非访问修饰符
- static
- final
三、包装类
如何把一个字符串类型的数据转换成数字类型呢?
1、什么是包装类
基本数据类型都有一个与其对应的包装器类,通常用于哪些不能够使用基本数据类型的场合,比如在集合对象中保存值;而且也提供许多静态方法来进行与其数据类型相关的操作
包装类可以是Integer、Long、Short、Byte、Double、Float、Boolean、Character
包装类与基本数据类型
基本类型 | 占用字节 | 默认值 | 对应的包装类 |
---|---|---|---|
byte | 1 | 0 | Byte |
short | 2 | 0 | Short |
int | 4 | 0 | Integer |
long | 8 | 0l | Long |
float | 4 | 0.0f | Float |
double | 8 | 0 | Double |
char | 2 | 00(空格) | Character |
boolean | 1 | false | Boolean |
2、字符串和数字之间转换
String类中的valueOf(参数)方法可以将其他类型的数据转换成字符串,这些参数的类型可以是:boolean,char,int,long,float,double和对象。
例:
double m1=3.456;
String s1=String.valueOf(m1); //将double类型的值转换成字符串
当需要将合法格式的字符串转换成基本数据类型时,可以使用相应基本类型的“包装类”的parse方法,
String str = "22";
int age = Integer.parseInt(str);
3、自动装箱和自动拆箱
如何把基本数据类型转换为包装类?
Integer a = Integer.valueOf(11);
如何将包装类对象转换为基本类型
int b = a.intValue();
那能不能把基本数据类型直接赋值给包装类对象,反之能不能把包装类对象直接赋值给基本数据类型?底层怎么实现的?
自动装箱(Autoboxing)和自动拆箱(Unboxing)是Java编译器提供的特性,用于方便地在基本数据类型和对应的包装类之间进行转换。
3.1、主要依赖方法:
-
在装箱过程,valueOf() 方法会创建一个新的包装类对象,并将基本数据类型的值封装到这个对象中
包装对象 变量 = 包装类.valueOf(数值);
-
在拆箱过程中,xxxValue() 方法会从包装类对象中提取出相应的基本数据类型值,并返回给调用者。
基本数据类型 名称 = 包装对象.xxxValue();
自动装箱和拆箱通常是由编译器在需要时自动进行的,所以我们在代码中并不需要显式地调用这些方法。
3.2、自动装箱
自动装箱是指将基本数据类型自动地转换为对应的包装类对象。
Integer a = 100;//自动装箱,将int类型的100转换为Integer对象
System.out.println(a);//100 且还是能调用toString方法
左边是一个包装类的对象,a本来是要存储对象的地址值的,而等号右边是基本数值。
当我们将基本数据类型赋值给对应的包装类对象时,编译器会自动进行装箱操作,将基本数据类型封装为包装类对象。
底层是通过Integer.ValueOf()进行装箱操作的(在编译期自动完成)。
3.3、自动拆箱
自动拆箱则是与自动装箱相反的过程,将包装类对象自动转换为对应的基本数据类型。
//自动拆箱:将包装类型转化成对应的基本类型
Integer b1 = new Integer(200);
int c = b1;//int c = b.intValue();
System.out.println(c);//200
当我们将包装类对象赋值给基本数据类型时,编译器会自动进行拆箱操作,将包装类对象中的值提取出来赋给基本数据类型。
底层通过intValue ()进行拆箱操作的(在编译期间自动完成)。
3.4、总结
自动装箱和自动拆箱可以使得基本数据类型和包装类之间的转换更加方便,使代码更简洁易读。它们在Java编译器的支持下,在需要时会自动地进行装箱和拆箱操作,减少了开发人员在基本数据类型和包装类之间的手动转换工作。
4、Character类的应用
接合String中的示例,统计一个字符串有多少个字符
isLetter(char ch)
确定指定的字符是否是一个字母。
isDigit(char ch)
确定指定的字符是否是数字
isLowerCase(char ch)
确定指定的字符是否是小写字符。
public class Main {
public static void main(String[] args) {
//比较优雅的方法
String str = "at7cH63OPbQ81";
int count=0;
for (int i = 0; i < str.length(); i++) {//如果有其它非字母不成立
if (!Character.isDigit(str.charAt(i))){
count++;
}
}
System.out.println(count);
}
}
四、常用工具类
1、常用时间类
JDK1.7之前常用时间类有;Date、Calendar、DateFormatJava1.0中包含了一个Date类,但是它的大多数方法已经在Java 1.1引入Calendar类之后被弃用了。
java.util.Date
import java.util.Date;
public class DateDemo{
public static void main(String[] args){
// 获取一个Date对象
Date today = new Date();
// 自动调用today对象的toString方法
System.out.println(today);
}
}
2、字符串转换Date
DateFormat是日期时间格式化子类的抽象类,提供Date和字符串表示之间的转换,是线程不安全的SimpleDateFormat是DateFormat的子类,也是线程不安全的,与DateFormat不同的是它可以自定义日期格式
2.1、字符串转换成时间
import java.text.DateFormat;
import java.text.SimpleDateFormat;
…..
DateFormat fmt =new SimpleDateFormat("yyyy-MM-dd");
String s = "1987-10-10";
Date date = fmt.parse(s);
2.1、时间成字符串
import java.text.DateFormat;
import java.text.SimpleDateFormat;
……
DateFormat fmt =new SimpleDateFormat("yyyy-MM-dd");
Date date = new Date();
String str = fmt.format(date);
3、JDK1.8新添加时间类
JDK1.8 新增的日期时间API:LocalDate、 LocalTime、 LocalDateTime
LocalDate是一个不可变的且线程安全的日期类
public class LocalDateDemo {
public static void main(String[] args) {
//获取当前时间的年月日
LocalDate now = LocalDate.now();
System.out.println(now);
System.out.println(now.getYear());
System.out.println(now.getMonth());
System.out.println(now.getDayOfMonth());
System.out.println(now.getDayOfWeek());
}
}
时间格式化操作:
注意:直接通过LocalDate,或LocalDateTime调用parse或format方法
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public static void main(String[] args) {
LocalDate now = LocalDate.now();
System.out.println(now);
String format = now.format(DateTimeFormatter.ofPattern("yyyyMMdd"));
System.out.println(format);
//format提供的值要和yyyyMMdd一致,否则会出错
LocalDate parse = LocalDate.parse(format,DateTimeFormatter.ofPattern("yyyyMMdd"));
System.out.println(parse);
}
4、随机数生成
4.1、Math.random()生成随机数
Math.random()方法可以生成一个0到1之间的随机浮点数
public class Main {
public static void main(String[] args) {
double random = Math.random();
System.out.println("随机数:"+random);
}
}
4.2、Random类生成随机数
Random类的实例用于生成伪随机数的流,常用方法有的nextInt()和nextDouble()等方法来生成随机整数和随机浮点数
public class Main {
public static void main(String[] args) {
Random random = new Random();
int randomInt = random.nextInt(10000);
System.out.println("随机数:"+randomInt);
}
}
生成四位随机数:int randomInt = random.nextInt(9000)+1000;
5、BigInteger
BigInteger
用来处理超大整形的
java.math.BigInteger
import java.math.BigInteger;
public class BigIntegerDemo {
public static void main(String[] args) {
long l = Long.MAX_VALUE;
System.out.println(l);
System.out.println(l + 1);
// 使用对象时必须通过变量调用其方法
BigInteger bigInt = new BigInteger("9223372036854775807");
bigInt = bigInt.add(new BigInteger("3"));
System.out.println(bigInt);
}
}
6、保留有效位数
DecimalFormat 是 NumberFormat 的一个具体子类,用于格式化十进制数字。DecimalFormat 包含一个模式 和一组符号 ,在做数字格式化时,DecimalFormat还是比较方便的。常用于保留小数点后几位、数字间用,
分割、四舍五入等场合
格式
DecimalFormat df = new DecimalFormat("#.00"); //或#.##
df.format(你要格式化的数字);
.00 表示两位小数 #.0000四位小数 以此类推…
new DecimalFormat("#.00").format(3.1415926)
7、BigDecimal
Java中的BigDecimal类是用于精确计算的高精度数字类。它可以处理比常规浮点类型(float、double)更大范围的数值,并避免了由于浮点数运算错误而引起的精度损失
如果是BigDecimal sum1 = new BigDecimal(“0.1”).add(new BigDecimal(“0.2”));这样操作是可以得到0.3的
double a = 0.1;
double b = 0.2;
double result = a + b;
System.out.println(result);//结果会是多少?
//处理方式一通过setScale方法
BigDecimal sum1 = new BigDecimal(a).add(new BigDecimal(b));
BigDecimal scale = sum1.setScale(2, RoundingMode.DOWN);
System.out.println(scale);
//处理方式二,直接在add方法中控制
BigDecimal sum = new BigDecimal(a).add(new BigDecimal(b),new MathContext(2, RoundingMode.DOWN));
System.out.println(sum);
MathContext类中两参数说明:
precision
:某个操作使用的数字个数;结果舍入到此精度roundingMode
:一个RoundingMode
对象,该对象指定舍入使用的算法。
8、可变参数
Java1.5增加了新特性
可变参数:适用于参数个数不确定,类型确定的情况,java把可变参数当做数组处理
可变参数的特点:
- 只能出现在参数列表的最后,且只能一个;
...
位于变量类型和变量名之间,前后有无空格都可以;- 调用可变参数的方法时,编译器为该可变参数隐含创建一个数组,在方法体中一数组的形式访问可变参数。
示例
public class Variable {
public static void main(String[] args) {
int sum = add(1, 1);
int sum2 = add(1, 1, 1);
int sum3 = add(1, 1, 1, 1);
System.out.println(sum);
System.out.println(sum2);
System.out.println(sum3);
}
public static int add(int x, int... args) {
int sum = x;
for (int i = 0; i < args.length; i++) {
sum += args[i];
}
return sum;
}
}
思维导图
本文来自博客园,作者:icui4cu,转载请注明原文链接:https://www.cnblogs.com/icui4cu/p/18802571