语法定义上的区别:静态变量前要加 static 关键字,而实例变量前则不加。
程序运行时的区别:
1.实例变量属于某个对象的属性,必须创建了实例对象,其中的实例变量才会被分配空间,才能使用这个实例变量。
2.静态变量不属于某个实例对象,而是属于类,所
以也称为类变量,只要程序加载了类的字节码,不用创建任何实例对象,静态变量就会被分
配空间,静态变量就可以被使用了。
3.实例变量必须创建对象后才可以通过这个对象来
使用,静态变量则可以直接使用类名来引用。
当一
个 static 方法被调用时,可能还没有创建任何实例对象,如果从一个 static 方法中发出对非
static 方法的调用,那个非 static 方法是关联到哪个对象上的呢?这个逻辑无法成立,所以,
一个 static 方法内部发出对非 static 方法的调用。
1.int 是 java 提供的 8 种原始数据类型之一
2.Java 为每个原始类型提供了封装类,Integer 是 java为 int 提供的封装类。
3.int 的默认值为 0,而 Integer 的默认值为 null,即 Integer 可以区分出未赋值和值为 0 的区别,int 则无法表达出未赋值的情况
4.在 JSP 开发中,Integer 的默认为 null,所以用
el 表达式在文本框中显示时,值为空白字符串,而 int 默认的默认值为 0,所以用 el 表达式在文本框中显示时,结果为 0,所以,int 不适合作为 web 层的表单数据的类型。
5.Integer 提供了多个与整数相关的操作方法,例如,将一个字符串转换成整数,Integer中还定义了表示整数的最大值和最小值的常量。
Math 类中提供了三个与取整有关的方法:ceil、floor、round,这些方法的作用与它们的英文名称的含义相对应
ceil 的英文意义是天花板,该方法就表示向上取整,Math.ceil(11.3)的结果为 12,Math.ceil(-11.3)的结果是-11
floor 的英文意义是地板,该方法就表示向下取整,Math.floor (11.6)的结果为 11,Math.floor (-11.6)的结果是-12;
round 方法,它表示“四舍五入”,算法为 Math.floor(x+0.5),即将原来的数字加上 0.5 后再向下取整,所以,Math.round(11.5)的结果为 12,Math.round(-11.5)的结果为-11。
说明:如果在修饰的元素上面没有写任何访问修饰符,则表示 friendly。
作用域
public | protected | friendly(空的) | private | |
---|---|---|---|---|
同一类中 | √ | √ | √ | √ |
同一包中(子类与无关类) | √ | √ | √ | x |
不同包的子类 | √ | √ | x | x |
不同包中的无关类 | √ | x | x | x |
Overload 是重载的意思,Override 是覆盖的意思,也就是重写。
重载Overload :即参数个数或类型不同
重写 Override 表示子类中的方法可以与父类中的某个方法的名称和参数完全相同,通过子类创建的实例对象调用这个方法时,将调用子类中的定义方法,这相当于把父类中定义的那个完全相同的方法给覆盖了,这也是面向对象编程的多态性的一种表现。
如果两个方法的参数列表完全一样,是否可以让它们的返回值不同来实现重载 Overload。这是不行的,这时候假设该类中有两个名称和参数列表完全相同的方法,仅仅是返回类型不同,java 就无法确定编程者倒底是想调用哪个方法了,因为它无法通过返回结果类型来判断。
synchronized 方法或代码块!似乎不太好!
只有多个 synchronized 代码块使用的是同一个监视器对象,这些 synchronized 代码块之间才具有线程互斥的效果,
假如 a 代码块用 obj1 作为监视器对象,假如 b 代码块用 obj2 作为监视器对象,那么,两个并发的线程可以同时分别进入这两个代码块中。
这里还可以分析一下同步的原理。
1.对于同步方法的分析,所用的同步监视器对象是 this
2.对于静态同步方法的分析,所用的同步监视器对象是该类的 Class 对象接着对如何实现代码块与方法的同步进行分析。
Servlet 被服务器实例化后,容器运行其 init 方法,请求到达时运行其 service 方法,service方法自动派遣运行与请求对应的 doXXX 方法(doGet,doPost)等,当服务器决定将实例销毁的时候调用其 destroy 方法。
1.实现了软件之间的解耦;
2.便于进行分工;
3.便于维护;
4.提高软件组件的重用;
5.便于替换某种产品,
6.便于产品功能的扩展;
7.便于适用用户需求的不断变化
1.StringBuilder是线程不安全的,但是运行效率高,如果一个字符串变量是在方法里面定义,这种情况只可能有一个线程访问它,不存在不安全的因素了,则用 StringBuilder。
2.如果要在类里面定义成员变量,并且这个类的实例对象会在多线程环境下使用,那么最好用
StringBuffer。
想要明白 hashCode 的作用,必须要先知道 Java 中的集合。
Java 中的集合(Collection)有两类,一类是 List,再有一类是 Set。前者集合内的元素是有序的,元素可以重复;后者元素无序,但元素不可重
复。
那么这里就有一个比较严重的问题了:要想保证元素不重复,可两个元素是否重复应该依据什么来判断呢?
这就是 Object.equals 方法了。
1.但是,如果每增加一个元素就检查一次,那么当元素很多时,后添加到集合中的元素比较的次数就非常多了。也就是说,如果集合中现在已经有 1000 个元素,那么第 1001 个元素加入集合时,它就要调用 1000 次 equals 方法。这显然会大大降低效率。
2.于是,Java 采用了哈希表的原理。可以简单理解,hashCode 方法实际上返回的就是对象存储的物理地址(实际可能并不是,可以假设是)。
3.这样一来,当集合要添加新的元素时,先调用这个元素的 hashCode 方法,就一下子能定位到它应该放置的物理位置上。
4.如果这个位置上没有元素,它就可以直接存储在这个位置上,不用再进行任何比较了;
5.如果这个位置上已经有元素了,就调用它的 equals 方法与新元素进行比较,相同的话就不存了,不相同就散列其它的地址。所以这里存在一个冲突解决的问题。这样一来实际调用 equals方法的次数就大大降低了,几乎只需要一两次。
Java 对于 eqauls 方法和 hashCode 方法是这样规定的:
1、如果两个对象相同,那么它们的 hashCode 值一定要相同;
2、如果两个对象的 hashCode 相同,它们并不一定相同
构造器 Constructor 不能被继承,因此不能重写 Override,但可以被重载 Overload。
接口可以继承接口。抽象类可以实现(implements)接口,抽象类是否可继承具体类。抽象类中可以有静态的 main 方法。
只有记住抽象类与普通类的唯一区别就是不能创建实例对象和允许有 abstract 方法。