修饰符
访问控制修饰符
private(私有的)自己专属:意味着被声明的成员或方法,除了本类,其他任何类都无法访问。
default(默认的)包访问权限:即不写任何关键字,就意味着相同包内的其他类(包括子类)可以访问,包外都不可以访问。
protected(受保护的)继承访问权限:使用protected关键字,就意味着被声明的成员或方法,在子类以及相同包内的其他类都可以访问的。
public(公共的)接口访问权限:使用public关键字,就意味着被声明的成员或方法对所有类都是可以访问的。
private
声明为private的方法,变量和构造函数只能在声明的类本身中访问
类和接口不能声明为:private。
如果类中存在公共getter方法,则可以在类中将变量声明为private。使用private修饰符是对象封装自身并隐藏来自外部世界的数据的主要方式(即私有变量,公共方法)
default
接口中的字段隐式为public static final,接口中的方法默认为public。
protected
受保护的访问修饰符不能应用于类和接口。 方法,字段可以声明为protected,但是接口中的方法和字段不能声明为protected。受保护的访问使子类有机会使用辅助方法或变量,同时防止非相关类尝试使用它。
public
如果尝试访问的公共类位于不同的包中,则仍需要导入公共类。 由于类继承,类的所有公共方法和变量都由其子类继承。
应用程序的main()方法必须声明为public。否则Java解释器无法调用它来运行该类。
访问控制和继承
强制执行以下继承方法规则 :
- 在超类中声明为public的方法也必须在所有子类中都是public。
- 在超类中声明为protected的方法必须在子类中也要声明为:protected或public; 不能声明为private。
- 声明为private的方法根本不能被继承,因此没有规则。
一、为什么不能用private修饰Java外部类?
因为如果使用private修饰Java外部类,那么这个类不能创建实例,这个类的属性和方法不能被访问,那么创建这个类毫无意义,所以不能使用private修饰Java外部类。
二、为什么不能用protected修饰Java外部类?
举个例子,如果类A用protected修饰,与类A不同包的类B想要访问类A的话,类B就必须是继承类A的(或者说类B必须为类A的子类),但是类B继承类A的前提又是类B可以访问到类A,有点绕对吧,仔细想想会发现这里是冲突的,其实这就说明了为什么不能用protected来修饰外部类。再说,protected是用来表示在继承关系中的访问权限的,在同一个包和子类中都可以访问,因为继承就是为了拥有父类的属性和方法,所以protected是用于修饰类的方法和属性的,也就是说,我想要这个类的属性和方法可以被任何子类继承,我就用protected。
非访问控制修饰符
- static修饰符用于创建类、方法和变量。
- final修饰符用于完成类,方法和变量的实现。
- abstract修饰符用于创建抽象类和方法。
- synchronized和volatile修饰符,用于线程。
static修饰符
由 static 关键字修饰的成员变量、成员常量、成员方法和内部类被称为静态成员变量、静态成员常量、静态成员方法和静态内部类。局部变量不能声明为static。
非静态的成员方法 和 静态的成员方法的区别
final修饰符
- final 关键字修饰基本数据类型时,其数值不能发生改变。
- final 关键字修饰引用数据类型时,其地址不能发生改变。
- final 关键字修饰成员方法时,表示该方法不能被重写。
- final 关键字修饰 class 类时,表示该类不能被继承。
public class Test {
final int value = 10;
// 以下是声明常量的示例:
public static final int BOXWIDTH = 6;
static final String TITLE = "Manager";
public void changeValue() {
value = 12; // 会出错,不能重新赋值
}
}
任何子类都不能覆盖final方法。 如前所述,final修饰符可防止在子类中修改方法。
声明final方法的主要目的是不让其它人改变方法的内容。
使用声明为final的类的主要目的是防止类被子类化。 如果一个类被标记为final,那么这个类不能被其它类继承。
abstract饰符
抽象(abstract)类不能实例化。如果一个类声明为抽象(abstract),那么唯一的目的是扩展该类。 一个类不能是同时是abstract和final(因为final类不能被扩展)。 如果一个类包含抽象方法,那么该类应该被声明为abstract。 否则,将抛出编译错误。 抽象类可以包含抽象方法以及普通方法。
抽象方法是在没有任何实现的情况下声明的方法。 方法体(实现)由子类提供。 抽象方法永远不会是最终的或严格的。 扩展抽象类的任何类都必须实现超类的所有抽象方法,除非子类也是抽象类,那就子子类实现。
public abstract class SuperClass {
abstract void m(); // 抽象方法
}
class SubClass extends SuperClass {
// 实现抽象方法
void m() {
// 实现代码.........
}
}
synchronized修饰符
synchronized关键字用于指示一次只能访问一个方法的方法。synchronized修饰符可以应用于四个访问级别修饰符中的任何一个。
public synchronized void showDetails(){
.......
}
transient修饰符
序列化的对象包含被 transient 修饰的实例变量时,java 虚拟机(JVM)跳过该特定的变量。
该修饰符包含在定义变量的语句中,用来预处理类和变量的数据类型。
public transient int limit = 55; // 不会持久化
public int b; // 持久化
volatile修饰符
volatile 修饰的成员变量在每次被线程访问时,都强制从共享内存中重新读取该成员变量的值。而且,当成员变量发生变化时,会强制线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。
一个 volatile 对象引用可能是 null。
public class MyRunnable implements Runnable
{
private volatile boolean active;
public void run()
{
active = true;
while (active) // 第一行
{
// 代码
}
}
public void stop()
{
active = false; // 第二行
}
}
通常情况下,在一个线程调用 run() 方法(在 Runnable 开启的线程),在另一个线程调用 stop() 方法。 如果 第一行 中缓冲区的 active 值被使用,那么在 第二行 的 active 值为 false 时循环不会停止。
但是以上代码中我们使用了 volatile 修饰 active,所以该循环会停止。
变量
变量是什么?简而言之,就是可以变化的量。
type varname [ = value][, varname [ = value] ...] ; 数据类型 变量名字 = 变量值。
变量的三要素:
1.数据类型 : 决定在内存中分配的空间
2.变量名 : 空间别名
3.值 :空间中存储的数据
注意点
- 每个变量在使用前都必须声明其类型,并且声明都必须是分号结束。
- 变量类型可以是基本类型。也可以是引用类型。
- 变量名必须是合法的标识符。
预热图:
成员变量
作用范围是整个类,相当于C中的全局变量,定义在方法体和语句块之外,一般定义在类的声明之下;成员变量包括实例变量和静态变量(类变量);
实例变量
独立于与方法之外的变量,无static修饰,声明在一个类中,但在方法、构造方法和语句块之外,数值型变量默认值为0,布尔型默认值为false,引用类型默认值为null;
类/静态变量
独立于方法之外的变量,用static修饰,默认值与实例变量相似,一个类中只有一份,属于对象共有,存储在静态存储区,经常被声明为常量,调用一般是类名.静态变量名,也可以用对象名.静态变量名调用;
静态变量(类变量)&实例变量区别:
A:调用方式
静态变量也称为类变量,可以直接通过类名调用。也可以通过对象名调用。这个变量属于类。
实例变量,只能通过对象名调用。这个变量属于对象。
B:存储位置
静态变量存储在方法区长中的静态区。
实例变量存储在堆内存。
C:生命周期
静态变量随着类的加载而存在,随着类的消失而消失。生命周期长。
实例变量随着对象的创建而存在,随着对象的消失而消失。
D:与对象的相关性
静态变量是所有对象共有,其中一个对象将它值改变,其他对象得到的就是改变后的结果.
实例变量则属对象私有,某一个对象将其值改变,不影响其他对象;
public class SE004_LeiBianLiangAndShiLiBianLiang {
public static void main(String[] args) {
Demo d1 = new Demo();
Demo d2 = new Demo();
}
}
class Demo{
static int i = 1; //类变量(静态变量)
int j = 1; //实例变量
public Demo(){
i++;
j++;
System.out.println(i+":"+j);
}
}
运行结果
2:2
3:2
局部变量
类的方法中的变量,声明在方法、构造方法或语句块中,在栈上分配,无默认值,必须经初始化.访问修饰符不能用于局部变量,
package com.cunyu.demo
public class Demo {
private String name; //成员变量、实例变量
private int age; //成员变量、实例变量
private int ID; //成员变量、实例变量
public static final String school = "卡塞尔学院"; //成员变量、静态变量(类变量)
public static String level = "SSS"; //成员变量、静态变量(类变量)
public int getAge() {
return age;
}
public int getId() {
return ID;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public void setId(int ID) {
this.ID = ID;
}
public void setName(String name) {
this.name = name;
}
public void study(){
String subject1 = "屠龙"; //局部变量
String subject2 = "炼金术"; //局部变量
System.out.println("学习科目: " + subject1 + "、" + subject2);
}
public static void main(String[] args) {
Demo demo = new Demo();
demo.setAge(23);
demo.setId(14000001);
demo.setName("楚子航");
System.out.println("ID: " + demo.getId() + "Age: " + demo.getAge() + "Name: " + demo.getName());
System.out.print("主修科目: ");
demo.study();
System.out.println("学院:" + Demo.school);
System.out.println("等级:" + Demo.level);
}
}
实例变量&局部变量区别:
1)作用域
实例变量:针对整个类有效。
局部变量:只在某个范围内有效。(一般指的就是方法,语句体内)
(2)存储位置
实例变量:随着对象的创建而存在,随着对象的消失而消失,存储在堆内存中。
局部变量:在方法被调用,或者语句被执行的时候存在,存储在栈内存中。当方法调用完,或者语句结束后,就自动释放。
(3)初始值
实例变量:有默认初始值。
局部变量:没有默认初始值,使用前必须赋值。
常量
常量:初始化后不能再改变的值。也就是不会变动的值。 常量名一般使用大写字符 语法:final 常量名 = 值;如:final String LOVE = ‘java‘;
包
为了更好的组织类,Java提供了包机制,用于区别类名的命名空间。 包语句的语法格式为:package pk1.pk2[.pk3[.pk4]]; 一般利用公司域名倒置作为包名:www.baidu.com --> com.baidu.www
为了使用某一个包的成员,需要在Java中导入包 语法: import 包名;
javaDoc
Javadoc用于描述类或者方法的作用。Javadoc可以写在类上面和方法上面。
常用标签
@author 标识一个类的作者 @version 指定类的版本 @deprecated 指名一个过期的类或成员 @throws 抛出异常 @param 参数情况 @return 返回值
用idea生成JavaDoc文档。点击前往