修饰符final
学习修饰符时,希望大家问自己问题?
- (1)修饰符本身的意思
- (2)它可以修饰什么?
- (3)它修饰后有什么不同?
- final:修饰符的一种
- 1、意思:最终的
- 2、final可以修饰:类(外部类、内部类)、变量(成员变量(类变量、实例变量)、局部变量)、方法(静态方法、非静态方法)
- 3、修饰后有什么不同?
- (1)修饰类:表示这个类不能被继承了,我们可以称它为“太监类”
- 例如:String、System、Math
- (2)修饰方法:表示这个方法不能被重写
- (3)修饰变量:表示这个变量的值不能被修改,即我们称为的“常量”
- 常量有两种:
- 一种是字面常量:例如:“hello”,12,‘a’
- 一种是final声明的变量:final int A = 10;
- 这里要说明一下,常量的命名应该是所有单词都大写,每个单词之间使用_
- 回忆:权限修饰符
- private、缺省、protected、public
public class TestFinal {
final int NUM = 10;
public int getNUM() {
return NUM;
}
/* public void setNUM(int num){
this.NUM = NUM;
}*/
public static void main(String[] args) {
Son s = new Son();
s.method();
final int A = 10;
//A = 20;//不能修改a的值
}
public static void change(final Circle c){
// c = new Circle();//错误的,因为c是常量
c.radius *= 2; //因为radius的前面没有final,可以修改
}
}
class Circle{
double radius;
}
final class TaiJian{
}
/*class Sub extends TaiJian{
}*/
class Father{
public void test(){
//...
}
public final void method(){
//..
}
}
class Son extends Father{
@Override
public void test() {
super.test();
}
/*public final void method(){
//..
}*/
}
修饰符native
native:也是一个修饰符
- 1、意思:原生的、本地的
- 2、可以修饰什么?
- 可以修饰方法
- 3、它修饰的方法有什么不同?
- 语法格式:
- 【修饰符】 class 类{
- 【其他修饰符】 native 返回值类型 方法名(【形参列表】);
- }
- native修饰的方法,看不见方法体。
- native修饰的方法,不是用Java语言实现的,而是调用了底层C/C++的代码,这些代码
- 被编译为.dll文件,让Java来执行的。
- 4、特殊
- (1)native方法,对于Java程序员来说,该怎么调用还怎么调用
- (2)子类还可以选择对它进行重写
修饰符static
static:也是一种修饰符
- 1、意思:静态的
- 2、可以修饰什么?
- (1)方法
- (2)成员变量
- (3)内部类:后面讲
- (4)代码块
- 3、修饰后有什么不同?
- (1)方法:我们称为“静态方法”或“类方法”
- ①这个方法,对于其他类来说可以用"类名.方法"进行调用,当然也可以使用"对象名.方法"进行调用,我们推荐用"类名.方法"
- ②静态方法中,是不允许出现:this,super,对本类的非静态属性、非静态的方法的直接使用代码的
- (2)成员变量:称为“类变量、静态变量”
- ①用static修饰的成员变量的值,表示是这个类型的所有对象“共享的”
- ②static修饰的成员变量的值,存储在方法区
- ③static修饰的成员变量的get/set也是静态的,
- ④如果在方法中有局部变量与static修饰的成员变量同名时,在静态变量前面加"类名."进行区别
- 结论:非静态的"对象名.",静态的用"类名."
- 问?黄色的脸,黑色的眼,中国人
- class Chinese{
-
private static String face = "黄色";
-
private static String eyes = "黑色";
-
private String name;
- }
static:静态 - 3、修饰后有什么不同?
- (1)方法:我们称为“静态方法”或“类方法”
- (2)成员变量:称为“类变量、静态变量”
- (3)内部类:后面讲
- (4)代码块
- 非静态代码块:
- 【修饰符】 class 类{
-
{
-
非静态代码块
-
}
- }
- 静态代码块:
- 【修饰符】 class 类{
-
static{
-
静态代码块
-
}
- }
- 特点:
- (1)每一个类的静态代码块只会执行一次
- (2)静态代码块在第一次使用这个类之前执行,即在类初始化时执行。
- 4、类初始化即执行类初始化方法:()
- 类初始化方法,一个类只有一个。它也是有编译器编译生成的,由两部分代码组成:
- (1)静态变量的显式赋值代码
- (2)静态代码块的代码
- 其中(1)和(2)是按照顺序执行
- 回忆:实例初始化方法()或(形参列表)
- 一个类可能有好几个实例初始化方法,有几个构造器就有几个实例初始化方法,它们由编译器根据:
- ①成员变量的显式赋值代码
- ②非静态代码块代码
- ③构造器的代码
- initialize:初始化
- class initialize:类初始化
一个类初始化时会先检查它的父类是否初始化,如果父类没有初始化,那么会先初始化父类。因为一个类只要初始化一次。
*
- (1)父类的初始化()
- ①父类的静态变量的显式赋值
- ②父类的静态代码块
- (2)子类的初始化()
- ①父类的静态变量的显式赋值
- ②父类的静态代码块
- 特殊:
- 静态方法是不能被重写的
public class TestClassInit {
public static void main(String[] args) {
/*Father f = new Father();
System.out.println("-------------------");
Son s = new Son();*/
Son s = new Son();
/*Father f = new Son();//多态引用
System.out.println("----------------");
f.assign();//静态方法在编译期间就确定了,不需要在运行时动态绑定
*/ }
}
class Father{
private static String info = assign();
static{
System.out.println("(1)父类的静态代码块");
}
public static String assign(){
System.out.println("(3)assign()方法");
return "Father";
}
}
class Son extends Father{
private static String info = assign();
static{
System.out.println("(2)子类的静态代码块");
}
public static String assign(){
System.out.println("(4)assign()方法");
return "Son";
}
}
类初始化与实例初始化
(1)先完成父类的类初始化
(2)再完成子类的类初始化
(3)父类的实例初始化方法
(4)子类的实例初始化方法
public class TestInit2 {
public static void main(String[] args) {
DemoZi zi1 = new DemoZi();
System.out.println("-------------------");
DemoZi zi2 = new DemoZi();
}
}
class DemoFu{
{
System.out.println("(1)Demo的非静态代码块1");
}
static{
System.out.println("(2)Demo的静态代码块1");
}
private static String info = assign();
private String message = getMessage();
static{
System.out.println("(3)Demo的静态代码块2");
}
{
System.out.println("(4)Demo的非静态代码块2");
}
public DemoFu(){
System.out.println("(5)无参构造");
}
public static String assign(){
System.out.println("(6)assign()方法");
return "hello";
}
public String getMessage(){
System.out.println("(7)getMessage()方法");
return "msg";
}
}
class DemoZi extends DemoFu{
{
System.out.println("(8)");
}
static{
System.out.println("(9)");
}
private static String info = assign();
private String message = getMessage();
static{
System.out.println("(10)");
}
{
System.out.println("(11)");
}
public DemoZi(){
System.out.println("(12)");
}
public static String assign(){
System.out.println("(13)");
return "hello";
}
public String getMessage(){
System.out.println("(14)getMessage()方法");
return "msg";
}
}
/*
* 对于T来说,就完成类初始化
*
* 创建对象,调用类的实例初始化<init>()或<init>(String str)
*
*
* (1)静态变量的显式赋值
* k = 0;
t1 = new T("t1");
<init>(String str)
①j = print("j");
public static int print(String str){
System.out.println((++k) + ":" + str + " i=" + i + " n=" + n); 1:j i=0 n=0
++n; n=1 k=1
return ++i; i=1
}
② {
print("构造块");
public static int print(String str){
System.out.println((++k) + ":" + str + " i=" + i + " n=" + n); 2:构造块 i=1 n=1
++n; n=2 k=2
return ++i; i=2
}
}
③public T(String str){
System.out.println((++k) + ":" + str + " i=" + i + " n=" + n); 3:t1 i=2 n=2
++n; n=3 k=3
++i; i=3
}
* t2 = new T("t2");
<init>(String str)
①j = print("j");
public static int print(String str){
System.out.println((++k) + ":" + str + " i=" + i + " n=" + n); 4:j i=3 n=3
++n; n=4 k=4
return ++i; i=4
}
② {
print("构造块");
public static int print(String str){
System.out.println((++k) + ":" + str + " i=" + i + " n=" + n); 5:构造块 i=4 n=4
++n; n=5 k=5
return ++i; i=5
}
}
③public T(String str){
System.out.println((++k) + ":" + str + " i=" + i + " n=" + n); 6:t2 i=5 n=5
++n; n=6 k=6
++i; i=6
}
i = print("i");
public static int print(String str){
System.out.println((++k) + ":" + str + " i=" + i + " n=" + n); 7:i i=6 n=6
++n; n=7 k=7
return ++i; i=7
}
n = 99;
* (2)静态代码块
* static{
print("静态块");
public static int print(String str){
System.out.println((++k) + ":" + str + " i=" + i + " n=" + n); 8:静态块 i=7 n=99
++n; n=100 k=8
return ++i; i=8
}
}
*/
public class T {
public static int k = 0;
public static T t1 = new T("t1");
public static T t2 = new T("t2");
public static int i = print("i");
public static int n = 99;
public int j = print("j");
{
print("构造块");
}
static{
print("静态块");
}
public T(String str){
System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);
++n;
++i;
}
public static int print(String str){
System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);
++n;
return ++i;
}
public static void main(String[] args) {
}
}
java.util.Arrays
API:应用程序编程接口,俗称,帮助文档
*
- java.util.Arrays:
- (1)public static int binarySearch(int[] a,int key)
- 使用二分搜索法来搜索指定的 int 型数组,以获得指定的值。
- 要求数组是有序的,否则结果不确定。
- 如果key在a数组中存在,就返回找到的第一个的下标,如果不存在返回负数。
- (2)public static int[] copyOf(int[] original,int newLength):从original原数组中复制得到一个新数组,
- 新数组的长度为newLength
- (3)public static int[] copyOfRange(int[] original,int from,int to):从original原数组中把[from,to)复制出来,构成新数组
- 要求from必须在original的合理下标范围内,to可以超过长度
- (4)public static boolean equals(int[] a,int[] a2):比较两个数组的长度和内容是否一致
- (5)public static void fill(int[] a,int val):把a数组的元素中val填充
- (6)public static void sort(int[] a):把数组a按照升序排列
- (7)public static String toString(int[] a):把a数组的元素,遍历,拼接为一个字符串返回,效果[1,3,5]
Object:是所有引用数据类型的根父类
*
- 那么根据多态,Object类型的变量,形参,就可以接收任意的引用数据类型的对象,包括数组
- 和数组有关的常用的方法:java.lang.System类
- public static native void arraycopy(Object src, int srcPos,Object dest, int destPos,int length);
- 第一个参数:src 原数组对象
- 第二个参数:srcPos 从原数组的[srcPos]下标开始复制
- 第三个参数:dest 目标数组对象
- 第四个参数:destPos 目标数组从[destPos]开始存储
- 第五个参数:length 表示从原数组复制几个元素
- 说明:如果src和dest是同一个数组的话,那么就会实现数组的元素的移动效果
- srcPos > destPos :往左移动 一般用于删除
- srcPos < destPos :往右移动 一般用于插入
public class TestSystemArrayCopy {
public static void main(String[] args) {
String[] arr = {"hello","world","java",null,null};
int total = 3;//实际的总元素
/* //实现删除arr[0]元素
System.arraycopy(arr, 1, arr, 0, 2);
arr[2] = null;*/
//实现在“hello"和"world"中间插入"guigu"
System.arraycopy(arr, 1, arr, 2, 2);
arr[1] = "guigu";
System.out.println(Arrays.toString(arr));
}
}
哪些方法不能被重写?
- (1)final修饰的
- (2)static修饰的
- (3)private修饰的
-
因为私有的在子类中不可见
- (4)如果跨包的话,修饰符缺省的也不能被重写,因为缺省的跨包不可见
abstract(后面讲)
*
- 外部类:
- 权限修饰符:public和缺省的
- 其他修饰符:final、
- 方法:
- 权限修饰符:四种
- 其他修饰符:final、static、native
- 成员变量:
- 权限修饰符:四种
- 其他修饰符:final、static
- 代码块:
- 修饰符:static
变量的分类
- 1、成员变量
- (1)类变量:静态的成员变量
- (2)实例变量:非静态的成员变量
- 2、局部变量
- 区别:
- 1、声明的位置
- (1)成员变量:类中方法外
- (2)局部变量:
-
方法()中形参列表
-
方法体{}中局部变量
-
代码块中局部变量
- 2、在内存中存储的位置
- (1)成员变量:
- 类变量:方法区
- 实例变量:堆
- (2)局部变量:
- 栈
-
虚拟机栈:非native方法的局部变量
-
本地方法栈:native方法的局部变量
- 3、修饰符
- (1)成员变量:
-
4种权限修饰符
-
static,final
- (2)局部变量:final
- 4、生命周期
- (1)成员变量:
- 类变量:
- 随着类的加载而分配空间,随着类的卸载而消亡
- 每一个对象是共享
- 实例变量:
- 每一个对象是独立
- 随着对象的创建而分配空间,随着对象被垃圾回收而回收
- (2)局部变量
- 方法调用时,在栈中分配空间,方法调用结束就消亡
- 5、作用域
- (1) 成员变量:
- 类变量:
- 在本类中随便用
- 在其他类中,用"类名.“或"对象.”
- 实例变量:
- 在本类中除了静态成员中不能用,其他随便用
- 在其他类中,用"对象."
- (2)局部变量
- 有作用域,超过作用域就不能使用了