一、static:

  1、static是一个标识符

    - 有static修饰的成员表明该成员是属于类的;

    - 没有static修饰的成员表明该成员是属于实例/对象的。

  2、static修饰的成员(Field、方法、初始化块),与类共存亡;static修饰的成员建议总是通过类名来访问,虽然它也可以通过实例来访问(实质也是通过类来访问的),所以平时若在其他程序中见到通过实例/对象来访问static成员时,可以直接将实例/对象 替换成类名;

  3、程序都是先有类再有对象的,有可能出现有类但没有实例/对象的情况,反过来绝对不可能出现有实例/对象却没有类的现象。

  4、类加载时会把属于类的Field存放到永生代堆内存中。

  规则:

  A、static修饰的成员不允许访问非static成员,非static成员可以访问static成员;

  B、this引用、super都丕允许出现在static成员中;

  C、若Field是实例/对象的,相当于前面省略了this.  , 若Field是类的则相当于前面省略了类名.

注意点:若自己写程序永远都不要使用对象/实例去调用static修饰的方法、Field,若看到其他程序出现实例/对象去调用static修饰的方法、Field,我们阅读时则先把对象换成类名.

 public class TestStatic{
private int age;
private String name;
private static String gender;
private double weight; public void test(String name){
System.out.println("他/她叫: " + name);
} public static void main(String[] args){
TestStatic ts = new TestStatic();
ts.test("小猴子");
//通过对象ts来访问static成员,可以替换成类名.gender
//因为gender是string引用变量且属于成员变量,若程序员没给它赋初始值,系统会默认给个null值它
System.out.println(ts.gender);
System.out.println(TestStatic.gender);
}
}
 public class TestStatic2{
static int count = 99;
int age;
{
age = 22;
test();
} static{
test();
//age = 13; //static成员不能访问非static成员
} public void way(){
System.out.println("age值为: " + age);
} public static void test(){
//static方法引用了非static修饰的age,报错
//System.out.println("age的值为: " + age);
System.out.println("~~这是一个test方法~~");
} public static void main(String[] args){
//定义了一个t2引用变量但t2并未指向任何对象
TestStatic2 t2 = null;
TestStatic2 t3 = new TestStatic2();
//对于static修饰的Field、方法,直接打印时相当于前面省略了类名
System.out.println(count); //t2.count
//成员变量前必须有主调对象且有static修饰的方法不能直接访问没有static修饰的变量
System.out.println(t3.age); //t3.age;
}
}

二、final:

  final作为一个修饰符,只能修饰:变量、方法和类。

  1、final修饰变量

    --final修饰的变量只能被赋值一次且赋值后不可改变。

   A、final修饰成员变量:

    Java成员变量默认可以由系统执行初始化,程序员可以不指定初始化,但final修饰的成员变量必须由程序员执行初始化

    [原因]:如果final修饰的成员变量由系统执行初始化,那它的值只能是0、0.0、null、false、\u0000,且还不能改变,那么该变量则会变得毫无价值

    若final修饰【实例变量】,可以在以下3个地方指定初始值:

     ①、定义时指定初始值;

     ②、初始化块中指定初始值;

     ③、构造器中指定初始值。

    注意:final修饰的变量只能指定一次初始值且普通方法是不允许为final实例变量赋值的。

 public class TestFinal{
//final修饰实例变量必须指定初始值且只能在定义时、初始化块、构造器中指定。
final int age = 20;
final double weight;
/*
{final修饰的变量只能被赋值一次。
weight = 150;
}*/ {
System.out.println("~~实例初始化块~~");
} public TestFinal(){
weight = 140;
} /* 普通方法不能为final修饰的变量赋值
public void setWeight(){
this.weight = weight;
}*/ public static void main(String[] args){
TestFinal tf = new TestFinal();
//实例变量必须拥有主调者
System.out.println(tf.weight);
}
}

    若final修饰【类变量】,只可以在以下两个地方指定初始值:

     ①、定义时指定初始值;

     ②、类初始化块中指定初始值。

   B、final修饰局部变量:

    Java的局部变量默认就必须由程序员来指定初始值。

    final修饰局部变量后,只有【一个变化】:一旦赋值后就不能再改变了。

 public class TestFinal3{
public static void main(String[] args){
final int age;
age = 12;
System.out.println(age);
//final修饰age后,age只能赋值一次,否则报错"可能已分配变量age"
//age = 22;
//System.out.println(age);
}
}

   C、final修饰的变量,它会被执行“宏替换”。如果final修饰的变量,可以【在编译的时候就确定】它的值,那么这个【变量就不存在】“宏替换” -- 就是查找、替换

 public class  FinalConstant {
public static void main(String[] args) {
String s1 = new String("疯狂java");
String s2 = new String("疯狂java");
System.out.println(s1 == s2); //false //JVM会把所有用过的String对象进行缓存
String s3 = "fkjava.org";
String s4 = "fkjava.org";//第二次用的是缓存中的fkjava.org对象
System.out.println(s3 == s4); //true //由于+前后的值都是"直接量",可以直接计算
String s5 = "疯狂" + "软件";
//在编译的时候,编译器已经把"+运算"计算出来,由于+前后的值都是"直接量",可直 //接计算
String s6 = "疯狂软件" ;//JVM在编译时就自动去掉+号
//s5、s6两个引用变量是否相等【必须指向同一个对象才相等】。
System.out.println(s6 == s5); //true String s7 = "疯狂";
String s8 = "java";
//由于s7、s8都是变量,他们的值只有在运行时才能确定下来
//因此s9、s10的值只能在运行是动态的确定,都不会缓存,因此无法直接使用缓存中的值
String s9 = s7 + s8;
String s10 = s7 + s8;
System.out.println(s9 == s10); /*
final String s11 = "fkjava";
final String s12 = ".org";
String s13 = s11 + s12;
String s14 = s11 + s12;
System.out.println(s13 == s14); //true */ // final修饰的变量,【声明时就指定了初始值】,但他们的初始值在编译时不能确定, //所以不能执行宏替换,所以s11、s12只有在运行时才能确定
final String s11 = s9; //s11的字符序列是:疯狂java
final String s12 = s10;//s12的字符序列是:疯狂java
String s13 = s11 + s12;
String s14 = s11 + s12;
System.out.println(s13 == s14); //false //final修饰的变量,【声明时就指定了初始值】,【而且初始值在编译就可以确定】
//那么这个变量就不存在,s15/s16会执行“宏替换”,也就是这两个变量根本就不存 //在,所有出现s15的地方都会替换成"fkjava",s16替换成".org"
//final String s15 = "fkjava";
//final String s16 = ".org";
/*String s17 = s15 + s16;
String s18 = s15 + s16;*/ String s17 = "fkjava" + ".org";
String s18 = "fkjava" + ".org";
System.out.println(s17 == s18); //true }
}

  3、final修饰方法:

   final修饰的方法不能被重写@Override;

   好处:禁止父类的方法被重写,避免破坏父类方法

   注意点:final与private结合没有实际意义,两者存一即可(private本身就不能被重写)。

  4、final修饰类:

   final类不能有子类,由于它不能有子类,所以它的方法能可以被更好的保护,典型的final类有:String、System、Math和包装类。

疯狂java学习笔记之面向对象(八) - static和final的更多相关文章

  1. Java学习笔记之面向对象、static关键字

    一周Java学习总结 今天就总结理清一下关于面向对象和面向过程的程序设计的一些不同特点,以及讲下static关键字. 面向对象 现在接触的Java是面向对象的,现在的程序开发几乎都是以面向对象为基础的 ...

  2. 疯狂java学习笔记之面向对象(一) - 定义类、方法、构造器

    Java面向对象 1.定义类 2.创建对象.调用方法 类和对象: 某一类对象的概念定义. 比如:人类 - 抽象出来的概念(不特指某个人) 对象 - 在类的概念下产生的一个实例,它就是一个对象了. ja ...

  3. 疯狂java学习笔记之面向对象(六) - 构造器重载、方法重载和方法重写

    一.方法重载(Overload): Java允许同一个类中定义多个同名方法,只要形参不一样就可以,如果同一个类中包含了两个或两个以上方法名相同的方法,但形参列表不同,则被成为方法重载(两同一异). 同 ...

  4. 疯狂java学习笔记之面向对象(五) - 封装、继承、多态

    一.封装: 封装的概念: - 合理的隐藏:隐藏不想被外界操作的Field.方法.构造器 - 合理的暴露:一般就是希望给别人调用的方法 e.g:显示器(按键暴露出来操作,但实际的东西/细节方法被隐藏起来 ...

  5. 疯狂java学习笔记之面向对象(四) - this关键字

    Java中this关键字主要有以下两个方法: 1.this引用 - 可用于任何非static修饰的方法和构造器中,当this用于方法中时,它代表调用该方法的实例/对象;当this用于构造器中时,它代表 ...

  6. 疯狂java学习笔记之面向对象(三) - 方法所属性和值传递

    方法的所属性: 从语法的角度来看:方法必须定义在类中 方法要么属于类本身(static修饰),要么属于实例 -- 到底是属于类还是属于对象? 有无static修饰 调用方法时:必须有主调对象(主语,调 ...

  7. 疯狂java学习笔记之面向对象(二) - 成员变量与局部变量

    Java变量按其作用域可分为:成员变量和局部变量.注意:在Java中是没有全局变量这个概念的 一.成员变量: 成员变量是在类中定义的变量,具体可分为类变量与实例变量--有无static修饰 实例变量的 ...

  8. 疯狂java学习笔记之面向对象(九) - 抽象和接口

    一.抽象(abstract): 1.抽象类: 使用abstract修饰的类就是抽象类; 相比于普通类抽象类增加了支持抽象方法的功能,但也丢失了创建实例的功能(抽象类中不能创建实例),其他普通类有的抽象 ...

  9. 疯狂java学习笔记之面向对象(七) - super关键字

    super有以下两大作用: 1.起限定作用:强制去访问父类的成员(Field.方法) 2.起调用作用:指定/显示调用父类的某个构造器 super调用规则: 1.子类构造器总会调用父类构造器一次,默认情 ...

随机推荐

  1. 虚拟机中的centos在nat模式下连不上外网

    这两天需要配置ftp服务器,可是虚拟机在nat模式下死活连不上外网,主机能够通过该ssh与虚拟机进行连接,虚拟机也能ping同一网段主机的IP地址,但就是ping不通外网, 开始我是这样配置的: 主机 ...

  2. iOS小技巧总结,绝对有你想要的

    原文链接 在这里总结一些iOS开发中的小技巧,能大大方便我们的开发,持续更新. UITableView的Group样式下顶部空白处理 //分组列表头部空白处理 UIView *view = [[UIV ...

  3. 1 mysql的安装

    win10 总之前期的步骤大概有:1下载安装:2 安装好后配置环境变量:3:登陆数据库 1:安装 mysql有安装版和直接解压就可以用的,据说大神都是安装的直接解压的,但鉴于自己是小白,就整了个安装版 ...

  4. hadoop+javaWeb的开发中遇到包冲突问题(java.lang.VerifyError)

    1.HDFS + WEB 项目 报java.lang.VerifyError... 异常 抛异常: Exception in thread "main" java.lang.Ver ...

  5. Android的两种事件处理机制

    UI编程通常都会伴随事件处理,Android也不例外,它提供了两种方式的事件处理:基于回调的事件处理和基于监听器的事件处理. 对于基于监听器的事件处理而言,主要就是为Android界面组件绑定特定的事 ...

  6. Pyqt QSplashScreen启动画面

    多大数应用程序启动时都会在程序完全启动时显示一个启动画面,在程序完全启动后消失.程序启动画面可以显示一些有关产品的信息,让用户在等待程序启动的同时了解有关产品的功能,也是一个宣传的方式.QSplash ...

  7. [LeetCode] Remove Duplicates from Sorted List

    Given a sorted linked list, delete all duplicates such that each element appear only once. For examp ...

  8. 手机访问 localhost

    为了测试开发的手机网站,常常需要使手机直接访问本地网络.在这个过程中碰到几个问题,记下来供以后参考 1. 在本地主机运行apache后,使用localhost和127.0.0.1可以访问页面,但使用I ...

  9. bootstrap 练习

    bookList.html <!DOCTYPE html> <html lang="zh-cn"> <head> <!-- 父路径 --& ...

  10. FP-Growth算法及演示程序

    FP-Growth算法 FP-Growth(频繁模式增长)算法是韩家炜老师在2000年提出的关联分析算法,它采取如下分治策略:将提供频繁项集的数据库压缩到一棵频繁模式树(FP-Tree),但仍保留项集 ...