Java核心技术卷I
常用的dos命令
dos不区分大小写,linux不同,linux严格区分大小写
#盘符切换 d:
#查看当前目录下的所有文件 dir
#切换目录 cd.. cd 目录的绝对地址
#清理屏幕 cls linux命令:clear
#退出终端 exit
#查看电脑的ip ipconfig linux命令;ifconfig
#打开应用
calc
mspaint 画板
notepad 记事本
#ping 命令
ping 命令 可以查看的网站的ip,测试网络是否通畅
#文件操作
md [目录名] 创建目录 linux命令:mkdir -p 递归创建
rd [目录名] 删除目录 linux命令:rmdir 只能删除空文件 rm -rf [文件或目录] 强制删除
cd>[文件名] 新建文件 linuxmingl:touch创建空的文件
del [文件名] 删除文件
Java特性
面向对象: 万物皆对象
动态性:反射
跨平台
可移植性
分布式
多线程
安全性
-
三高:高可用,高性能,高并发
-
JavaSE -->JavaEE
JDK JRE JVM
JDK:Java Development Kit 编写
JRE:Java RuntimeEnvironment 运行
JVM:Java Virtual Machine
Java命名规则
Java的基本程序设计结构
java基本数据类型:
-
java属于强类型语言:要求变量严格反而和规定,所有的变量必须先定义才能使用
-
弱类型语言如:javaScript
-
8种基本数据类型:4种整形、2种浮点型、1种用于表示Unicode编码的字符单元的字符类型char和一种用于表示真值的boolean类型
-
Java没有任何无符号类型(unsigned)
8大基本数据类型:
类型 | 大小 | 长度 |
---|---|---|
short | 1字节 | -128-127 |
byte | 2字节 | -32768-32767 |
int | 4字节 | -2147483648-2147483647 |
long | 8字节 | -92233720368547758-9223372036854775807 |
char | 2字节 | |
float | 4字节 | |
double | 8字节 | |
boolean | 1位 |
字节
进制转换
https://blog.csdn.net/final__static/article/details/89405945
浮点数
浮点数计算遵循IEEE754规范。下面表示溢出和出错情况的三个特殊的浮点值:
-
正无穷大
-
负无穷大
-
NAN(不是一个数字)
eg:一个正数除以0的结果为正无穷大。计算0/0或者负数的平方根结果为NAN
检测“非数值”:
if(Double.isNAN(x))//check whether x is "not a number"
char类型
Unicode编码单位可以便是为十六进制值,其范围\u0000到\uffff
- 转义字符:
所有的ASCII码都可以用“\”加数字(一般是8进制数字)来表示
转义字符 | 意义 | ASCII码值(十进制) |
---|---|---|
\a | 响铃(BEL) | 007 |
\b | 退格(BS) ,将当前位置移到前一列 | 008 |
\f | 换页(FF),将当前位置移到下页开头 | 012 |
\n | 换行(LF) ,将当前位置移到下一行开头 | 010 |
\r | 回车(CR) ,将当前位置移到本行开头 | 013 |
\t | 水平制表(HT) (跳到下一个TAB位置) | 009 |
\v | 垂直制表(VT) | 011 |
\ | 代表一个反斜线字符’’’ | 092 |
’ | 代表一个单引号(撇号)字符 | 039 |
" | 代表一个双引号字符 | 034 |
? | 代表一个问号 | 063 |
\0 | 空字符(NUL) | 000 |
\ddd | 1到3位八进制数所代表的任意字符 | 三位八进制 |
\xhh | 十六进制所代表的任意字符 | 十六进制 |
注意:
1. 区分,斜杠:"/" 与 反斜杠:"" ,此处不可互换
2. \xhh 十六进制转义不限制字符个数 ‘\x000000000000F’ == ‘\xF’
变量
声明一个变量之后,必须用赋值的语句对变量精选显示初始化
常量
利用关键字final指示常量
类的常量定义位于main方法的外部,因此,在同一个类的其他方法中也可以使用这个常量。如果这个常量被声明为public,那塔塔类的方法也可以使用这个常量
形式参数和实际参数
运算符
二元算数运算符
x += 4 等价于 x = x+4
自增 自减运算符
++n n++
前缀方式先加1,后缀方式使用变量原来的值
int m = 7;
int n = 6;
int a = 2 * ++m;//now a is 16,m is 8
int b = 2 * n++;//now b is 14,n is 8
基本类型比较
import java.math.BigDecimal;
/**
* @program: JavaSE
* @description: 进制转换
* @author: codelwx
* @create: 2020-09-19 12:06
**/
public class JzConversion {
public static void main(String[] args) { //psvm
//整数拓展: 二进制0b 十进制0-10 八进制0 十六进制0x
int i = 10;
int i1 = 010; //八进制 末位数0-8,遇8进1 8
int i2 = 0x10; //十六进制 0-9 A-F 16
System.out.println(i); //sout
System.out.println(i1);
System.out.println(i2);
//浮点数: float double
/*
* float : 单精度浮点数
double : 双精度浮点数
两者的主要区别如下:
01.在内存中占有的字节数不同
单精度浮点数在机内存占4个字节
双精度浮点数在机内存占8个字节
02.有效数字位数不同
单精度浮点数有效数字8位
双精度浮点数有效数字16位
03.数值取值范围
单精度浮点数的表示范围:-3.40E+38~3.40E+38
双精度浮点数的表示范围:-1.79E+308~-1.79E+308
04.在程序中处理速度不同
一般来说,CPU处理单精度浮点数的速度比处理双精度浮点数快
如果不声明,默认小数为double类型,所以如果要用float的话,必须进行强转
例如:float a=1.3; 会编译报错,正确的写法 float a = (float)1.3;或者float a = 1.3f;(f或F都可以不区分大小写)
注意:float是8位有效数字,第7位数字将会四舍五入
* */
//浮点数不能直接拿来做比较 如果需要浮点数的比较可以使用BigDecimal工具类比较
int a = 10;
float f = 12.12f;
float f1 = f + a;
System.out.println(f1);//计算错误
BigDecimal b = new BigDecimal(f1);
float f2 = b.setScale(1, BigDecimal.ROUND_HALF_UP).floatValue();//通过函数转码
System.out.println(f2);
//float比较
float d = 123456f;
float d1 = f + 1;
System.out.println(d == d1);//false float是8位有效数字,第7位数字将会四舍五入 有限 舍入原则
//字符拓展
//所有字符的本质还是数字
char c1 = 'a';
char c2 = '中';
System.out.println((int) c1); //97 对应的ASCII码(大小写相差32) A 65
System.out.println((int) c2); //20013 unicode表 2字节 2E+16 = 65536
//转义字符
char c3 = '\u0061'; //unicode编码表
System.out.println(c3); // a
//常见转义字符 \r \t \n \' \\ \"
System.out.println("hello\nworld");//换行
//字符串比较
String str1 = new String("HELLo WORLD");
String str2 = new String("HELLo WORLD");
System.out.println(str1 == str2); // false
String str3 = "HELLo WORLD";
String str4 = "HELLo WORLD";
System.out.println(str3 == str4); // true
//布尔型比较
boolean flag = true;
if (flag) {
System.out.println("true");
}
}
}
类型转换
/**
* @program: JavaSE
* @description: 类型转换
* @author: codelwx
* @create: 2020-10-16 12:58
**/
public class TypeConversion {
public static void main(String[] args) {
int i = 128;
//Byte -128~127
byte b = (byte) i; //-128 内存溢出 要防止内存溢出
/**
* 强制类型转换:高到低
* 自动转换:低到高
* */
/*注意:
1.布尔类型不能转换
2.不能转换成不相干的类型
3.高容量转换低容量使用强转
4.可能出现内存溢出、精度丢失等情况
*/
System.out.println(i);
System.out.println(b);
}
}
类型转换_内存溢出
/**
* @program: JavaSE
* @description: 类型转换_内存溢出
* @author: codelwx
* @create: 2020-10-16 13:17
**/
public class Case01 {
public static void main(String[] args) {
//操作比较大的数的时候出现内存溢出的情况
//JDK7的新特性,使用_分隔
int money = 10_0000_0000;
int years = 20;
int total01 = money * years;
System.out.println(total01);//-1474836480 内存溢出
//错误处理
long total02 = money * years;
System.out.println(total02);//-1474836480 内存溢出(先计算在转换)
//正确处理
long total03 = money * ((long) years);//先把一个数转换成long
System.out.println(total03);//20000000000
}
}
枚举类型
在变量中很可能保存的是一个错误的值(如0或m)
enum Size = {SMALL,MEDIUM,LARGE,EXTRA_LARGE};
Size s = Size.MEDIUM;
Size只能存储这个类型声明中给定的某个枚举值,或者null值,null表示这个变量没有设置任何值。
字符串
-
子串:String类的substring方法可以从一个较大的字符串提取出一个子串
String str = "abcdef"; String sub = str.substring(0,3);//abc 在substring中从0开始计数,直到3为止,但不包括3。子串的长度3-0=3
-
拼接: Java语言允许使用+连接(拼接)两个字符串
String str = "123"; String add = str+"456";//123456
-
不可变字符串
Java文档中将String类对象称为不可变字符串,如同数字3永远是数字3一样,字符串“hello”永远包含字符h e l l o的代码单元序列,而不能修改其中的任何一个字符。
使用拼接的方式来修改字符串,虽然可行但会影响运行效率。但是,不可变的字符串却有一个有优点:编译器可以让字符串共享
Java的设计者认为共享带来的高效率远远胜过提取、凭借字符串所带来的低效率。
- 检测字符串是否相等
if("HELLO".equels(Hello))//检测是否相等
if("HELLO".equels("Hello"))
if("HELLO".equelsIgnoreCase(Hello))//检测是否相等,忽略大小写
if("HELLO".equelsIgnoreCase("Hello"))
==一定不能使用 == 运算符检测两个字符串是否相等!==这个运算符只能够确定两个字符串是否放置在同一个位置。如果字符串放置在同一个位置上,他们必然相等,但是,完全有可能将内容相同的多个字符串的拷贝放置在不同的位置上。
如果虚拟机始终将相同的字符串共享,就可以使用 == 符检测是否相等。但实际只有字符串 常量 是共享的,而+和substring等操作残生的结果并不是共享的。因此,千万不要使用 == 符测试字符串的相等性,以免在程序中出现糟糕的bug。
-
空串和Null串
空串”“是长度为0,内容为空的Java对象
if(str.length() == 0) if(str.equels("")) if(str == null) if(str != null && str.length() != 0)
-
构建字符串
StringBuilder builder = new StringBuilder();//构建空的字符串构造器 builder.append(ch);//append a single character builder.append(str);//append a single string String completedString = builder.toString();//得到一个String对象,其中包含构建器中的字符序列
JDK5.0中引入了StringBuilder类。这个类的前身是StringBUffer,其效率稍有些低,但允许采用多线程的方式执行添加或删除字符的操作。如果所有字符串在一个单线程中编辑(通常),则应该用StringBuilder替代。两个API是相同的。
-
字符串的输入输出
输入:
import java.util.Scanner; /** * @program: JavaSE * @description: Scanner测试 * @author: codelwx * @create: 2020-10-20 15:57 **/ public class ScannerTest { public static void main(String[] args) { Scanner in = new Scanner(System.in); System.out.println("What is you name?"); String name = in.nextLine(); System.out.println("How old are you"); int age = in.nextInt(); System.out.println("name:"+name+"\n"+"age:"+age); } }
输出:Java SE 5.0沿用了c语言函数的prinf方法
可以使用静态的String.format方法创建一个格式化的字符串,而不打印输出:
String massage = String.format("Hello,%s. Next year,you will be %d", name,age);
控制流程
块作用域
由一对花括号括起来的若干条简单的Java语言。块确定了变量的作用域。
不能在嵌套的两个块中声明同名的变量
条件语句
- if
if表达式返回两个结果:
* true:执行花括号里的内容
* flase:执行花括号以外的内容 执行else花括号
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
System.out.println("请输入判断的整型数字:");
int x = sc.nextInt();
if(x % 2 !=0){
System.out.println(x+"为奇数");
}else{
System.out.println(x+"为偶数");
}
}
- if else
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
System.out.println("请分别输入两个数字:");
double x = sc.nextDouble();
double y = sc.nextDouble();
if(x > y){
System.out.println(x+"大");
}else{
System.out.println(y+"大");
}
}
- if_else if
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("------成绩判断系统-----");
Scanner sc = new Scanner(System.in);
System.out.println("请输入你的成绩!");
int a = sc.nextInt();
if(a < 100){
if(a >=90 && a<= 100){
System.out.println("优秀!孩子你太棒了");
}else if(a >=80){
System.out.println("优,你距离优秀就差一点了哦!加油");
}else if(a >= 70){
System.out.println("一般般吧!良");
}else if(a >= 60){
System.out.println("小子,刚及格,咋在学啊!是我教的不够明白还是你天生就是武将啊?");
}else{
System.out.println("你小子算是废了,叫你爸妈在练一个小号吧!");
}
}
}
- for
public static void main(String[] args) {
// TODO Auto-generated method stub
int sum = 0;
for(int i = 1;i <= 100;i++){
if(i % 2 != 0){
sum += i;
}
}
System.out.println(sum);
}
在循环中,检测两个浮点数是否相等需要格外的小心。
for(double x = 0;x != 10;x += 0.1)..//由于舍入误差,最终可能得不到精确的值。因为0.1无法精确的用二进制表示,所以,x将从9.999 999 999 999 98跳到10.099 999 999 999 98。
- for循环嵌套
循环原理:
* 外层循环一次,内层循环一遍
* 外层循环代表行,内层循环代表列
public static void main(String[] args) {
// TODO Auto-generated method stub
//99乘法表
for(int i =1;i <= 9;i++ ){
for(int j = 1;j <= i;j++){
System.out.print(i+"*"+j+"="+i*j+" ");
}
System.out.print("\n");
}
}
- while
循环的三要素:
* 1.变量的初始化
* 2.while(循环条件:i < 10){}
* 3.i++;变量的叠加
先判断条件再执行循环
public static void main(String[] args) {
// TODO Auto-generated method stub
int x = 1;
while(x < 3){
System.out.println(x);
x++;
}
}
- do_while
//先循环再判断条件
public static void main(String[] args) {
// TODO Auto-generated method stub
int x = 1;
int sum = 0;
do{
sum += x;
x++;
}while(x <= 100);
System.out.println(sum);
}
- switch
中断控制流程语句
/*continue 终止本次循环,执行下次循环
经常用于求奇数或偶数的和,或某一条件不输出!
break 终止循环,跳出循环
注:print println :ln代表自动换行
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int sum = 0;
for(int i = 1;i <= 100;i++){
sum += i;
if(sum > 200){
break;
}
}
System.out.println(sum);
continue语句将控制转移到最内层循环的首部
大数值
BigInteger和BigDecimal
-
BigInteger:实现了任意精度的整数运算。
-
BigDecimal:实现了任意精度的浮点数运算。
使用静态的valueOf()可以将普通的数值转换成大数值
Java中的大数据:BigInteger和BigDecimal
https://blog.csdn.net/qq997404392/article/details/78085783
数组
1. 一维数组
1.1数组定义:存储相同数据类型的集合,数组的类型要和数据类型和数据的类型相吻合
1.1.1数组的元素{1, 2, 3}**
数组中的每个数据 叫数组的元
数组可以存储 基本数据类型和引用数据类型
1.1.2数组的长度:{1, 2, 3} c.length
数组中元素的个数叫数组的长度
1.2.3数组的索引: 数组的下标;下标从0 开始;从数组中取元素通过下标来取
在实验中我们获取下标时,直接取出下标并赋值一个int a = i;
1.1.4数组的创建:
1.数据类型[] 数组名
2.数据;类型 数组名[]
1.2.5数组的内存分配:
栈:存储引用数据类型的地址 当声明数组时,栈中没有分配内存地址,只有当数组实例化或赋值时才分配内存地址
堆:存储引用数据类型的值 当给数组赋值时,堆会自动开辟空间存储值,并通过地址来指向堆中的值
1.1.6数组赋值的两种方式:
-
静态赋值int[] a = {1,2,3,7}
-
动态赋值:
(1)先创建 空数组,确定数组的长度
(2)通过下标给数组赋值
a[0] = 1;
…
1.1.7数组的输出
一维数组用for循环输出
二维数组用for(){ for(){}}循环输出
利用Arrays类的toString方法。调用Arrays.toString(a),返回一个包含数组元素的字符串
案例:
给数组赋值
public static void main(String[] args) {
// TODO Auto-generated method stub
//1.静态赋值:声明数组的同时给数组赋值
int sum = 0;
int[] b ={1, 2, 3};//静态赋值方法1
int[] c = new int[]{1, 2, 3};静态赋值方法2
//2.动态赋值
int[] a = new int[5];//创建 空数组,确定数组的长度
a[0] = 1;
for(int i = 0;i < b.length;i++){
sum += b[i];
}
System.out.println("sum="+sum);
}
求平均值
public static void main(String[] args) {
// TODO Auto-generated method stub
int a[] = {1, 20, 5, 4, 10};
double sum = 0;
double avg = 0;
for(int i = 0;i < a.length;i++){
sum += a[i];
}
avg = sum/a.length;
System.out.println("sum="+sum);
System.out.println("avg="+avg);
}
求最大值及下标
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] arr = {1, 10, 5, 13};
int max = arr[0];//将第一个值赋值给变量
int index = 0;//接收下标
for(int i = 0;i < arr.length; i++ ){
if(arr[i] > max){//数组中的每一个值都和max比较
max = arr[i];
index = i;//获取下标
}
}
System.out.println("最大值:"+max+"下标:"+index);
}
冒泡排序
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] a = {5, 10, 20, 2, 9};
for(int i = 1; i < a.length;i++){
for(int j = 0;j < a.length-i;j++){
if(a[j] > a[j+1]){
int temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
for(int i = 0;i < a.length;i++){
System.out.print(a[i]);
}
}
数值复制
public static void main(String[] args) {
// TODO Auto-generated method stub
//定义一个原数组
int[] a = {1, 2, 3, 4, 5};
//定义一个目标数组
int[] b = {6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
for(int i = 0;i < b.length;i++){
System.out.print(b[i]+" ");
}
System.arraycopy(a, 1, b, 1, 4);//System.arraycopy(源数组,源数组中的起始位置, 目标数组,目标数组中的起始位置,要复制的数组元素的个数)
System.out.println("\n");
//复制的元素会将目标元素相位置的元素替换掉
for(int i = 0;i < b.length;i++){
System.out.print(b[i]+" ");
}
}
倒序
Arrays.sort(arr);//排序函数
for(int i = arr.length-1;i >= 0;i--){
System.out.print(arr[i]+" ");
}
2.多维数组
与一维数组一样,在调用new对多维数组进行初始化之前不能使用它。
public class 多维数组 {
/**多维数组:
* 1.每一行代表一个数组,列代表数组的长度
* 2.必须声明行数!
* 多维数组类型:1.矩形数组 2.锯齿形数组
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//二维数组的创建
int[][] a;
int b[][];
int[]c[];
//矩形二维数组
int[][] d = new int[3][2];//第一个[]代表数组的个数,第二个[]每个数组的长度
//动态赋值
d[0][0] = 1;
d[0][1] = 2;
d[1][0] = 1;
d[1][1] = 2;
d[2][0] = 1;
d[2][1] = 2;
//遍历输出数组,外循环是数组的个数,内循环的是每个数组的下标
for(int i = 0;i < d.length;i++){
for(int j = 0;j < d[i].length;j++){
System.out.print(d[i][j]+" ");
}
System.out.print("\n");
}
System.out.print("\n");
//锯齿形数组
int[][] s = new int[3][];//每个数组的长度不确定
//定义每个数组的长度,下标从0开始
s[0] = new int[2];
s[1] = new int[3];
s[2] = new int[4];
//赋值
s[0][0] = 1;
s[0][1] = 2;
s[1][0] = 1;
s[1][1] = 2;
s[1][2] = 3;
s[2][0] = 1;
s[2][1] = 2;
s[2][2] = 3;
s[2][3] = 4;
//遍历输出需要两个循环
for(int i = 0;i < s.length;i++){
for(int j = 0;j < s[i].length;j++){
System.out.print(s[i][j]+" ");
}
System.out.print("\n");
}
System.out.print("\n");
int[][] w = {{1, 2},{1, 2, 3},{1, 2, 3, 4}};
for(int i = 0;i < s.length;i++){
for(int j =0;j < w[i].length;j++){
System.out.print(w[i][j]+" ");
}
System.out.print("\n");
}
}
}
-
快速获取二维数组
System.out.print(Arrays.deepToSting(s));
对象和类
封装
从形式上看,封装不过是将数据和行为组合在一个包中,并对对象的使用者隐藏了数据的实现方式。对象中的数据称为实例域,操作数据的过程称为方法。对于每个特定类实例(对象)都有一组特定的实例域值。这些值的集合就是这个对象当前状态(state)。无论何时,只要对象发送一个消息,它的状态就有可能发生改变。
实现封装的关键在于绝对不能让类中的方法直接访问其他类的实例域。程序仅通过对象的方法与对象数据进行交互。
封装给对象赋予了“黑盒“的特征,这是提高重用性和可靠性的关键
对象和对象变量
在对象和对象变量之间存在着一个重要的区别
Date deadline;//声明
定义了一个对象变量deadline,它可以引用Date类型的对象。变量deadline不是一个对象,实际上也没有引用对象。此时,不能将任何Date方法应用与这个变量上。
Date birthday = new Date();
deadline = new Date();//定义
deadline = birthday;
dealine和birthday引用一个对象:
一个对象变量并没有实际包含一个对象,而仅仅引用一个对象
在Java中,任何对象变量的值都是对存储在另外一个地方的一个对象的引用。new操作符的返回值也是一个引用。
Date和Calender类
具体API可百度
当类库设计者意识到某个发那个发不应该存在时就把它标记为不鼓励使用。
用户自定义类
构造器
构造器总是伴随着new操作的执行而被调用而不能对一个已经存在的对象调用构造器来达到重新设置实力域的目的。
- 构造器与类同名
- 每个类可以有一个以上的构造器
- 构造器可以有0、1或多个参数
- 构造器没有返回值
- 构造器总是伴随着new操作一起调用
注意:不要在构造器中定义与实例域重名的局部变量。
隐式参数和显式参数
number007.raiseSalary(5);
隐式参数:number007
显式参数:5
显式参数明显的出现地列在方法声明中
- 在每个方法中,this表示 隐式参数
pbulic void raiseSalary(double byPercent){
double raise = this.salary * byPercent / 100;
this.salary = raise;
}
封装的优点
典型的访问器方法:
get方法。只返回实例域值,称为域访问器。
set方法。称为域更改器方法。
获取或设置实例域的值:
- 一个私有的实例域 private
- 一个共有的域访问器方法 get方法
- 一个共有的域更改器方法 set方法
类的访问权限
同一个类 | 同一个包 | 不同包的子类 | 不同包的非子类 | |
---|---|---|---|---|
Private | √ | |||
Default | √ | √ | ||
Protected | √ | √ | √ | |
Public | √ | √ | √ | √ |
final 实例域
确保每个构造器在执行之后,这个域的值被设置,并且在后面的操作中,不能够再对它进行修改。
//name域声明为final,构建后值不会再被修改,即没有setName方法
class Employee{
private final String name;
...
}
//存储在hireDate变量中的对象引用在对象构造之后不能被改变,而并不意味着hireDate对象是一个常量。任何方法都可以对hireDate引用对象调用setTime更改器
private final Date hireDate
静态域与静态方法
静态域
每个类中只有一个这样的域。每一个对象对于所有的实例域却都有自己的拷贝,如果有1000个Employee类的对象,则有1000个实例域。但是,只有一个静态域。它属于类,不属于任何独立的对象
静态常量
public class Math{
public static final PrintStream out = ...;
}
静态方法
使用情况:
- 一个方法不需要访问对象状态,其所需参数都是通过显式参数提供(eg:Math.pow(x,a))
- 一个方法只需要访问类的静态域。
/*static
* 修饰属性:
* 只能修饰全局变量,不能修饰局部变量
*
* 修饰方法
*
* 静态代码块:
* 当类被载入时,且只执行一次
*
*
* 访问的方式:
* System.out.println(x);static属性可直接被调用,普通全局变量需实例化对象那个调用
* 1.类名.属性
* 2.对象.属性
* 没有通过static修饰的全局变量只能通过对象调用
* 静态方法
* 1.类名.方法()
* 2.对象.方法()
* 注意:
* 1. 静态方法只能方法静态的属性(变量)和方法
* 2. 静态方法中不能使用this和super关键字
* 3. 静态方法不能被重写
* 4.static 不能修饰构造器
*
*
* */
public class Test {
private static String name;//修饰全局变量
private int age;
public static void show(){
//static 不能修饰局部变量
name = "小龙虾";
System.out.println(name);
}
static{
System.out.println("我是静态代码块!");
}
public static void main(String[] args) {
Test.name = "历史";
Test t = new Test();
t.show();
}
}
结果:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SjbcxJQr-1610596908341)(java%E5%9F%BA%E7%A1%80.assets/wps1-1603430796014.jpg)]
工厂方法
- 无法命名构造器
- 当使用构造器时,无法改变构造器的对象类型。
单例模式
import sun.security.jca.GetInstance;
/**
* @program: JavaSE
* @description: 单例模式
* @author: codelwx
* @create: 2020-10-23 13:30
**/
public class Singleton {
//一个私有的静态对象
private static Singleton sing = new Singleton();
//私有无参构造器
private Singleton(){}
//单例模式访问点
public static Singleton GetInstance(){
return sing;
}
public void work(){
System.out.println("I like work");
}
public static void main(String[] args) {
Singleton s = Singleton.GetInstance();
s.work();
}
}
方法参数
Java程序设计总是采用 按值调用。方法得到的是所有参数值的一个拷贝,特别是,方法不能修改传递给它的任何参数变量的内容。
两种类型:
- 基本数据类型(数字、布尔值)
- 对象引用
使用情况:
- 一个方法不能修改一个基本数据类型的参数(即数值型和布尔型)
- 一个方法不能让对象参数引用一个新的对象
- 一个方法可以改变一个对象参数的状态
对象构造
重载
Java允许重载任何方法,而不只是构造器方法。要完整的描述一个方法,需要指出方法名以及参数类型。这叫做方法的签名。
返回类型不是方法签名的一部分。不能有两个名字相同、参数类型相同却返回不同类型值的方法。
默认域初始化
在构造器中如果没有显示的给域赋予初值,就会被自动的赋为默认值。数值类型为0、布尔值为false、对象引用为null。然而,只有缺少程序设计经验的人才会这样做。如果不明确地对域进行初始化,就会影响程序代码的可读性。
必须明确的初始化方法中的局部变量。
无参构造器
如果在编写一个类时没有编写构造器,那么系统就会提供一个无参数构造器。这个构造器将所有的实例域设置为默认值。
参数名
public Employee(String name,double salary){
this.name = name;
this.salary = salary;
}
调用另一个构造器
如果构造器的第一个语句形如this(…),这个构造器将调用同一个类中的另一个构造器。
public Employee{
this("HELLO"+nextId,s);
nextId++;
}
采用这种方式使用this关键字非常有用,这样对公共的构造器代码部分只编写一次即可。
类的设计技巧
- 一定要保证数据私有。绝对不要破坏封装性
- 一定要对数据初始化。最好不要依赖系统的默认值
- 不要在类中使用过多的基本类型
- 不是所有的域都需要独立的域访问器和域更改器
- 将职责过多的类进行分解
- 类名和方法名要能够体现它们的职责