第二周学习总结:
一.javaSE基础复习阶段,目前已经学习到继承(以上是平时遇到的重点)
常见面试题:基本类型与包装类型的区别 (int 与Integer的区别)
1、Integer是int的包装类,int则是java的一种基本数据类型
2、Integer变量必须实例化才能使用,int变量不需要实例化
3、Integer的默认值是null,而int的默认值是0
4、Integer实际是一个对象的引用,当new一个Integer对象时,实际是生成一个指针指向该对象,而int是基本数据类型,直接存储数值
通过new出来的字符串例如
String s1 = new String(“abc”);
String s2 = new String(“abc”);
System.out.println(s1 == s2);
//false
代表即在堆里面创建了abc又在常量池中创建了abc实例。
通过字面量创建出来的字符串例如
String s1 = "abc";
String s2 = "abc";
System.out.println(s1 == s2);//true
代表只在常量池中创建
通过intern方法的话
类的定义
语法
public class 类名 {
//可编写0至n个属性
数据类型 变量名1;
数据类型 变量名2;
//可编写0至n个方法
修饰符 返回值类型 方法名(参数){
执行语句;
}
}
注意:
- public类的类名必须和类所在文件的文件名一致
- 如果不是public类,那么类名与类所在的文件名可以不一致
- 类名的命名规范是:帕斯卡命名法
this可以调用重载的构造方法
例如:我们知道学生姓名和成绩,不知道学号,但是显示学生信息时要求将学号显示为”未知“,而不是null
分析:
有两种情况
- 知道姓名和成绩,不知道学号
- 知道姓名,成绩,学号
所以要设计两种构造的重载,设计结果如下
class Student {
String name;
int score;
String no;
Student(String name,int score){
this(name,score,"未知");//构造方法内部的this()表示调用本类的其他构造方法
}
Student(String name,int score,String no){
this.name= name;
this.score= score;
this.no = no;
}
}
特别注意:下面的代码是错误的
Student(String name,int score){
this.name = name;
this(name,score,"未知");//这里报错
}
因为this调用本类其他构造方法时,必须时构造方法内的第一行代码。
对象数组
需求:
- 班级里有5名学生,输入每名学生的姓名和总成绩。
- 根据学生总成绩从高到低排名,显示学生名次、姓名、总成绩。
分析:
- 有哪些对象?有学生对象,有班级对象
- 对象有什么属性和方法?
- 学生有姓名,成绩的属性,学生不需要方法
- 班级有多名学生的属性,班级有排序方法,输出的方法
代码:
1:创建学生类
public class Student {
//属性
String name;
int score;
//构造
public Student(String name, int score) {
this.name = name;
this.score = score;
}
}
班级类
public class ClassInfo {
//属性
Student []stus = null;
//构造函数初始化班级大小
public ClassInfo(int size){
this.stus = new Student[size];
}
//排序方法
public void sort(){
if(this.stus.length==0){
return;
}
for (int i = 0; i < this.stus.length-1; i++) {
for (int j = 0; j < this.stus.length - i - 1; j++) {
if(this.stus[j].score<this.stus[j+1].score){
Student temp = this.stus[j];
this.stus[j] = this.stus[j+1];
this.stus[j+1] = temp;
}
}
}
}
//输出方法
public void print(){
for (int i = 0; i < stus.length; i++) {
System.out.printf("姓名:%s,成绩%d,名次:%d",stus[i].name,stus[i].score,(i+1));
System.out.println();
}
}
}
测试类
public class Test {
public static void main(String[] args) {
//1:创建5个学生
Student s1 = new Student("刘茂兵",60);
Student s2 = new Student("田舍翁",80);
Student s3 = new Student("杨礼之",90);
Student s4 = new Student("余晨",65);
Student s5 = new Student("乔思义",70);
//2:创建班级
ClassInfo classInfo = new ClassInfo(5);
classInfo.stus[0] = s1;
classInfo.stus[1] = s2;
classInfo.stus[2] = s3;
classInfo.stus[3] = s4;
classInfo.stus[4] = s5;
//3:排序
classInfo.sort();
//4:输出
classInfo.print();
}
}
运行结果
姓名:杨礼之,成绩90,名次:1
姓名:田舍翁,成绩80,名次:2
姓名:乔思义,成绩70,名次:3
姓名:余晨,成绩65,名次:4
姓名:刘茂兵,成绩60,名次:5
static与instance的区别
static:静态(属于类,只有一份)
instance:实例(实例也叫对象,就是new出来的堆的内存空间,实例是每个对象专有的,每new一次就分配一次内存)
-
实例变量是在new类时在堆中分配内存的。
-
构造函数可以为实例属性初始化。构造函数不会为静态属性初始化。
-
由于静态属性是所有对象共有的,所有对象不就是类吗,因此静态属性也称为类属性,或者类变量,或者类成员。
-
既然静态属性属于类,不属于某个具体的对象,因此在new对象时,不会给静态属性分配内存。那静态时什么时候分配内存呢?
-
当在程序运行期间,首次出现类名时,会暂时停止程序运行,去为类的静态属性分配内存,然后继续运行。
-
静态变量被分配在方法区中,常驻内存,永不回收。静态变量只有一份。相当于c语言的全局变量。
-
静态变量由类名操作,由类名赋值,取值。
-
类名调用静态属性时,可以省略类名。
-
常见问题
public class Test { static int age; public static void main(String[] args) { age = 2; } } //正确
public class Test { static int age; public static void main(String[] args) { Test.age = 2; } } //正确 如上例,"age"其实前面就省略了TEST
public class Test { public static void main(String[] args) { } public void sayHello(){ } public static void sayHi(){ sayHello(); } } //错误 在程序运行时,第一次出现类名时即创建静态变量与方法且会一直存在,对象变量不知道什么时候创建与消失
public class Test { public static void main(String[] args) { } public void sayHello(){ this.sayHi(null); } public static void sayHi(Test t){ t.sayHello(); } }
public class Test { int age; public static void main(String[] args) { age = 2; } } //错误 在程序运行时,第一次出现类名时即创建静态变量与方法且会一直存在,对象变量不知道什么时候创建与消失
public class Test { int age; public static void main(String[] args) { new Test().age = 2; } } //正确
public class Test { int age; public static void main(String[] args) { new Test().age = 2; } public static void sayHi(){ } public static void sayHello(){ this.sayHi(); } } //错误 在程序运行时,第一次出现类名时即创建静态变量与方法且会一直存在,对象变量不知道什么时候创建与消失
如果让类只有自己能调用,别人不能调用可以这样设置(即单例模式,构造函数私有化)
public class Test { private Test(){ new Test(); } }
private不能修饰类
private class Classinfo{//报错,private不能修饰类
}
public class Student {
}
再看一个例子
public class Student {
int age;
private class Classinfo{//不报错,因为Cassinfo类是Student类的成员
}
}
private可以修饰类的成员,无论类的成员是什么(内部类,变量,方法等但是就是不能是类)。
子类如何调用父类构造函数捏?
- 子类通过关键字super()调用父类构造函数
- super()必须放在子类构造函数的第一行代码
解释:创建子类对象时的运行规则
- 第一个方面:构造函数的调用顺序问题
- new子类时,首先调用子类构造函数,但是不执行子类构造函数
- 子类构造函数被调用后立即调用父类的构造函数。
- 第二个方面:属性初始化顺序的问题
- 从Object类开始初始化
- 然后依次从父到子的顺序初始化(哪个类定义的属性,就由哪个类负责初始化)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lS9NeooJ-1658653203431)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\image-20220722145721924.png)]
下面的代码可以正常运行吗?
public PersonalDepartment(int count) {
super();
this();
this.count = count;
}
答:不可以,super与this不可以同时出现。对于super而言方法内部没写super则第一行默认写了super.而对于this而言调用此对象的其他方法而方法有其他的super就相当于调用了两次父类这是不允许的。
静态代码块
下列代码执行结果是什么
package qmfx2;
public class Test7{
public static void main(String[] args) {
Test t1 = new Test();
Test t2 = new Test();
Test t3 = new Test();
}
}
class Test{
String name;
{
System.out.println("我是构造代码块");
}
static {
System.out.println("我是静态代码快");
}
public Test(){
System.out.println("我是Test类的构造方法");
}
}
代码执行顺序:
静态代码块、构造代码块、构造方法
static修饰的代码块会随着class文件一同加载(属于优先级最高的代码块)
静态代码块内容只会输出一次
二.算法题总结
数组部分马上刷完。了解动态窗口解法,固定位置赋值解法等,仍然需要不断总结反复的刷。
三.新内容探索
redis部分已经完结,下面就是结合自己的学习笔记慢慢看不断复习.
System.out.println(“我是构造代码块”);
}
static {
System.out.println(“我是静态代码快”);
}
public Test(){
System.out.println(“我是Test类的构造方法”);
}
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/a03129ec902d4d4bb055492bc385a74d.png#pic_center)
代码执行顺序:
静态代码块、构造代码块、构造方法
<u>**static修饰的代码块会随着class文件一同加载(属于优先级最高的代码块)**</u>
<u>**静态代码块内容只会输出一次**</u>
## 二.算法题总结
数组部分马上刷完。了解动态窗口解法,固定位置赋值解法等,仍然需要不断总结反复的刷。
## 三.新内容探索
redis部分已经完结,下面就是结合自己的学习笔记慢慢看不断复习.