Java中的修饰符分为权限修饰符和特征修饰符
权限修饰符 | 意义 |
---|---|
public | 公共的 |
protected | 受保护的 |
默认不写 | 默认的 |
private | 私有的 |
特征修饰符 | 意义 |
---|---|
final | 最终的 不可更改的 |
static | 静态的 |
abstract | 抽象的 |
native | 本地的 |
transient | 瞬时的 短暂的------>序列化 |
synchronized | 同步的 线程问题 |
volatile | 不稳定的 |
权限修饰符
【1】权限修饰符在类的关系中的访问权限
权限修饰符 | 可以访问 | 可以访问 | 可以访问 | 可以访问 |
---|---|---|---|---|
public | 本类 | 同包 | 子类 | 当前项目中任意类的位置只要有对象都可以访问 |
protected | 本类 | 同包 | 子类(通过子类对象在子类范围内部访问) | |
默认不写 | 本类 | 同包 | ||
private | 本类 |
- 注:同包意思为,在同一个
package packageName;
下的成员
【2】权限修饰符能修饰什么 ,范围如何
- 权限修饰符可以用来修饰 类本身 和类中的成员(除程序块)
- 权限修饰符用来修饰类的时候只有两个可以用(public 默认不写)
- 权限修饰符都可以用来修饰类中其他成员
【3】以后强烈建议大家属性不要公有的---->非常不安全
- 对属性本身的封装:属性私有(封装在类中)
- 提供操作属性相应的方式(公有的方法)
public class Person {
//属性
private int age;
//方法
//设计一个方法 用来取得age属性的值
// 提供条件?不需要 返回值? 获取的age的值
public int getAge(){
return this.age;
}
//设计一个方法 用来给age属性赋值
// 提供条件? age的值 返回值?void
public void setAge(int age){
if(age<0){
System.out.println("对不起 您还没出生呢 请给正确的年龄范围");
this.age = -1000;
//抛出异常
}else if(age>130){
System.out.println("对不起 您已经升仙啦 请给正确的年龄范围");
this.age = -1000;
//抛出异常
}else {
this.age = age;
}
}
}
package person;
public class Test {
public static void main(String[] args){
//创建类的过程是在Java中描述的过程
//1.创建对象
Person p = new Person();
//2.对象的引用 . 调用属性
p.name = "张三";
p.setAge(18);
p.sex = "男";
System.out.println("今年"+p.getAge());
}
}
【4】既然以后大家都这样操作属性 属性及其操作属性的方法都有其命名的规约
age------> setAge getAge
myAge--> setMyAge getMyAge
特征修饰符
1.final
final可以修饰什么 ?修饰以后有什么特点 ?
【1】修饰变量
-
变量是存在栈上的临时空间。
-
如果在定义变量时没有赋初始值,给变量一次存值的机会(因为变量在栈内存空间内 没有默认值 如果不给机会 就没法用啦),一旦变量被存储了一个值 ,若用final修饰后 则不让再次改变 ----> 相当于常量啦(值没法动)。(类似于C语言中的const)
-
注意变量类型是基本类型还是引用类型,如果修饰的变量是基本数据类型 ,则变量内的值不让更改—常量;如果修饰的变量是引用数据类型, 则变量内的地址引用不让更改。
【2】修饰属性
-
属性是存在对象空间,对象又是存在堆上的,所以属性是全局变量 ,存储在堆内存的对象空间内一个空间
-
属性如果没有赋值 ,有默认值存在的
-
属性用final修饰后 必须给属性赋初值 否则编译报错,特点与修饰变量一致
-
注意变量类型是基本类型还是引用类型
【3】修饰方法
- 方法是最终的方法 ,不可更改,即final修饰的方法 要求不可以被子类重写(覆盖)
【4】修饰类本身
- 类是最终的 不可以更改,==此类不可以被其他子类继承 ==
- 通常都是一些定义好的工具类:如Math , Scanner ,Integer ,String …
2.static
可以修饰什么,修饰后有什么特点
【1】可以 修饰属性 ,修饰方法 ,修饰块 ,修饰类(内部类)
【2】特点
1.静态元素在类加载时就初始化啦,创建的非常早,此时没有创建对象
2.静态元素存储在静态元素区中,每一个类有一个自己的区域,与别的类不冲突
3.静态元素只加载一次(只有一份),全部类对象及类本身共享
4.由于静态元素区加载的时候,有可能没有创建对象,可以通过类名字直接访问
5.可以理解为静态元素不属于任何一个对象,属于类的
6.静态元素区Garbage Collection无法管理,可以粗暴的认为常驻内存
7.非静态成员(堆内存对象里)中可以访问静态成员(静态区)
8.静态成员中可以访问静态成员(都存在静态区)
9.静态成员中不可以访问非静态成员(静态元素属于类 ,非静态成员属于对象自己)
10.静态元素中不可以出现this或super关键字(静态元素属于类)
static的应用场景和设计模式的引入
【1】设计模式 23种 (内功心法)
- 设计模式不是知识点
- 设计模式是一种设计经验的总结
- 设计模式用来解决某些场景下的某一类问题的---->通用的解决方案
- 有了设计模式之后 可以让代码更容易被理解 确保了复用性 可靠性 可扩展性
【2】设计模式分为三类
设计模式 | 用途 | 数量 | 形式 |
---|---|---|---|
创建型模式 | 用于解决对象创建的过程 | 5种 | 单例模式 工厂方法模式 抽象工厂模式 建造者模式 原型模式 |
结构型模式 | 把类或对象通过某种形式结合在一起 构成某种复杂或合理的结构 | 7种 | 适配器模式 装饰者模式 代理模式 外观模式 桥接模式 组合模式 享元模式 |
行为型模式 | 用来解决类或对象之间的交互 更合理的优化类或对象之间的关系 | 11种 | 观察者模式 策略模式 模板模式 责任链模式 解析器模式 迭代子模式 命令模式 状态模式 备忘录模式 访问者模式 中介者模式 |
【3】单例模式(Singleton)的引入及对象创建的思考
- 假设我们要设计一个 搜索系统
public class myBaidu{
public void 搜索(String keyword){
}
}
- 当我们要使用系统去搜索的时候,要先new创建一个myBaidu对象 ,调用搜索的方法 ,使用一次方法执行一遍;如果同一时间有很多很多很多很多人在使用这个系统,就会每一个人都创建一个对象去调用对应的方法,这样子就会申请甚多内存空间,服务器也会承受不住
- 所以我们想到能不能只创建一个对象, 堆内存中就只开辟一个空间,调用一次方法—>在栈空间临时执行一次,方法执行完空间就回收啦
- 所以我们就引入单例模式,只创建单个对象,供一个类共享
【4】单例模式的实现
- 1.私有的构造方法
- 2.私有的静态的当前类对象作为属性
- 3.公有的静态的方法返回当前类对象
对象的加载方式 | 什么时候加载 | 优点 | 缺点 |
---|---|---|---|
饿汉式(立即加载) | 对象启动时就加载啦 | 不会产生对象没有就拿来使用的问题 避免空指针异常 | 启动项目加载的对象过多 有些还没有使用 产生服务器承载压力的问题 |
懒汉式(延迟加载) | 对象什么时候用到了 才会加载 | 启动项目时候只有需要的加载 不需要的还没有创建 不会浪费空间 | 可能会由于没有操作好 导致异常(很严谨) |
生命周期托管(单例对象别人帮我们处理) | 对象加载过程交给别人 | (后面才学) | (后面才学) |
【5】单例模式实现代码
package singleton;
public class SingleTon {
//通过我的设计 让这个类只能创建一个对象
//正常情况下每一个类都有默认无参数的构造方法----公有 在外面可以随意创建
//1.让构造方法变成私有---保证外面不可以随便创建对象
private SingleTon(){}
//2.单例 不是无例 --- 在本类中的某个成员位置上创建唯一的一个对象
//在以下的四个位置 写一行new SingleTon
//属性
//方法------不行 每一次执行都会产生一个过程 保证不了唯一
//构造方法--不行 私有 本身就是这个构建过程
//块--------不行 没有返回值 创建了对象也无法给别人使用
//2.在当前类中存在一个私有的静态属性 是当前类类型的
private static SingleTon single;//直接 private static SingleTon single = new Singleton(); 叫立即加载----》 饿汉式
//3.提供一个获取单个对象的方法给用户
// 返回值 将对象返回出去
public static SingleTon getSingleTon(){// get类名 newInstance
if(single == null) {
single = new SingleTon();//延迟加载的方式 懒汉式
}
return single;//引用类型
}
}
package singleton;
public class TestMain {
public static void main(String[] args){
SingleTon s1 = SingleTon.getSingleTon();
SingleTon s2 = SingleTon.getSingleTon();
System.out.println(s1==s2);//true 比较地址
System.out.println(s1.equals(s2));//true Object类继承过来的 默认也比地址
System.out.println(s1);//类全名@hashCode--->16进制的整数
System.out.println(s2);
}
}
/*********运行结果*************/
true
true
singleton.SingleTon@b4c966a
singleton.SingleTon@b4c966a
【6】单例模式简图
3.native
【1】native本地的
- Java源代码中看到native就已经再也看不见后续代码,后续会调用其他的编程语言C++ / C语言执行内存的操作 ,帮我们操作内存
- 如Object类中一个方法 :hashCode
public native int hashCode(); //底层调用C++的代码帮我们把地址转成16进制的数返回给我们