主要知识点:
1、java中四种修饰符的限制范围。 |
2、Object类中的方法。 |
3、接口和抽象类的区别,注意JDK8的接口可以有实现。 |
一、Java中四种修饰符的限制范围
private:只有本类可访问
default:在整个包内都可被访问
protected:当前类,子类,同包下
public:所有类都可访问
Q:一个内部类可以访问其外部类的private属性吗?为什么?
A:在内部类保留一个对外部类的引用,当在内部类中访问一个变量时,如果在内部类找不到,
它就会通过外部类的引用,到外部去查找.private是说,是在本类中可以访问的控制权限.
内部类也是外部类的一部分.也就说,内部类可是使用外部类定义的一切变量.静态内部类除外.
public class Outer {
private String outVal;
class Inner{
public void printVal(){
System.out.println(outVal);
}
}
}
Q:一个类可以访问其内部类的private属性吗?为什么?
A:在任何情况下,外部类都不能直接访问内部类的成员,必须先获取内部类的引用才行或者如果是静态内部类的话由内部类的类名调用.
class Outer{
class Inner{
private int number=5;
}
public int getNumber(){
return new Inner().number;
}
}
public class Hello {
public static void main(String[] args){
System.out.println(new Outer().getNumber());
}
}
二、Object类方法介绍
Object类是所有类的超类。
Object类的结构如下:
1、registerNatives方法注册一些本地方法;native表示该方法的实现java本身并没有完成,而是有c/c++来完成,
形成.dll文件。
private static native void registerNatives();
static {
registerNatives();
}
2、返回的是一个class对象,后面可以跟class类的方法。用的是谁的构造函数,那么getClass返回的就是谁的类型;经常用于java反射机制
public final native Class<?> getClass();
3、返回的对象的地址值;String类中对此方法进行了重写;方法调用得到一个计算公式得到的 int值
Object:
public native int hashCode();
String:
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
4、判断两个对象是否相等,比较的是对象的地址
public boolean equals(Object obj) {
return (this == obj);
}
5、实现对象的浅复制,只有实现了Cloneable接口才可以调用该方法,否则抛出CloneNotSupportedException异常。
protected native Object clone() throws CloneNotSupportedException;
6、返回类名+@+hashcode的十六进制表示方式;一般类都会重写该方法
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
7、唤醒在该对象上等待的某个线程
public final native void notify();
8、唤醒在该对象上等待的所有线程
public final native void notifyAll();
9、wait方法就是使当前线程等待该对象的锁,当前线程必须是该对象的拥有者,也就是具有该对象的锁。wait()方法一直等待,直到获得锁或者被中断。wait(longtimeout)设定一个超时间隔,如果在规定时间内没有获得锁就返回。
调用该方法后当前线程进入睡眠状态,直到以下事件发生。
(1)其他线程调用了该对象的notify方法。
(2)其他线程调用了该对象的notifyAll方法。
(3)其他线程调用了interrupt中断该线程。
(4)时间间隔到了。
此时该线程就可以被调度了,如果是被中断的话就抛出一个InterruptedException异常。
public final native void wait(long timeout) throws InterruptedException;
public final void wait(long timeout, int nanos) throws InterruptedException {
if (timeout < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException(
"nanosecond timeout value out of range");
}
if (nanos > 0) {
timeout++;
}
wait(timeout);
}
public final void wait() throws InterruptedException {
wait(0);
}
10、该方法用于释放资源。因为无法确定该方法什么时候被调用,很少使用。
垃圾回收时,垃圾回收器调用对象 确定不再有对该对象的引用。一个子类会覆盖改方法来处理系统资源或执行其他清理。
protected void finalize() throws Throwable { }
三、接口和抽象类区别
区别(java8之前):
1、接口不能有方法体,抽象类可以有
2、接口可以被多实现,抽象类只能单继承
3、接口里所有的属性和方法都只能是静态的和public的
4、实现接口的类必须要实现接口中的方法,但继承类可以不重写父类中的方法
5、abstract关键字只能修饰抽象类的类和方法,不能修饰字段
6、抽象类不能被实例化(无法使用new关键字创建对象实例),只能被继承
7、含有抽象方法的类必须定义成抽象类
java8:
1、接口也可以有方法体(default关键字);
2、接口也可以有静态方法,并且可以通过接口名.方法名调用方法
interface ITest {
void test1();
default void test2(){
System.out.println("test2接口的方法");
}
static void test3(){
System.out.println("接口的静态方法");
}
}
public class Test implements ITest{
@Override
public void test1() {
System.out.println("Test1");
}
public static void main(String[] args) {
ITest test = new Test();
test.test1();
test.test2();
ITest.test3();
}
}
输出的结果:
Test1
test2接口的方法
接口的静态方法