面向对象(上)部分问题的理解

什么是构造方法
构造方法是一个对象在创建时直接自动执行的对变量进行初始化的方法。构造方法的函数名和类名相同,没有返回值和返回类型,但可以被public和private修饰。如果没有自定义构造方法则系统会给出默认无参构造方法,构造方法也可以自定义并重载。

什么是抽象
抽象时从被研究对象中舍弃个别的,非本质的或与研究主旨无关的次要特征,抽取与研究有关的共性内容加以考察,形成对研究问题正确、简明扼要的认识。
如:从人和马中抽象出来共同的动物属性。

对象位于内存何处
在程序运行时,类会被加载到方法区中,而其中的静态变量加载到方法区的静态存储区中。在类用new创建对象时,对象会被放置在堆内存中,在堆中开辟空间存放对象的域变量,而对象的方法实质上还是在调用类在方法去存储的方法。

声明能引用对象的实质是什么
创建引用时,方法中引用会被加载到栈中,引用保存的是对象在堆中的地址,相当于一个遥控器去操纵这个对象。

对象和基本数据类型作为参数传递时的不同之处
这就类似c++中的值传递和引用传递,基本数据类型传递的是一个副本,这个副本对本体没有任何影响,而引用传递则是将这个引用的对象传递给参数中的引用,两个引用指向的是同一个对象,所以形参可以改变对象中的变量。

public static void add(int a) {
		a++;
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int x=3;
		add(x);
		System.out.println(x);//输出3
		
}
	
class A{
	int x=1;
	void fA(){
		x++;
	}
}
public class test {

	public static void add(A a) {
		a.fA();
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		A a1=new A();
		System.out.println(a1.x);//输出1
		add(a1);
		System.out.println(a1.x);//输出2
		
}
	
}

对象在什么条件下成为垃圾
Java和c++对象很大的一个不同之处在于c++的类在不用时需要主动delete,但是Java则不用,会由Java虚拟机自动回收,那么什么时候回收,又怎么去判断是否回收了呢?
JVM会在一个对象没有被任何引用所关联时将其判断为垃圾对象,但此时这个对象并不会被立即回收,而是会等待JVM去进行一次清理内存时回收,JVM会在内存不足时立即清理一次内存,此时对象将会被回收。而怎么证明被回收了呢,其中一个方法就是使用finalize方法,利用这个方法去告诉使用者该对象已经被回收了。finalize方法相当于析构函数,会在对象被回收时调用,但是这个回收的时间并不确定,如果需要回收,也可以使用system.gc()方法进行显式回收。

class A{
	protected void finalize() throws Throwable {
		System.out.println("我死了QAQ");
	}
}
public class test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		A a1=new A();
		a1=null;
		System.gc();
		System.out.println("over");
}
}
//输出:
//over
//我死了QAQ

从上面的例子中我们可以看出gc()方法释放了对象A的内存,析构方法finalize被调用,但是有一个问题出现了,over比finalize先被调用。这是因为JVM对有finalize方法的对象的回收实际上是调用了一个优先级低的Finalizer线程去执行它,这个线程执行需要一定时间,所以就算使用gc方法也不能保证立即就能回收。并且对象的finalize方法还有可能让对象死里逃生,这个这里就不详细论述了。

class A{
	protected void finalize() throws Throwable {
		System.out.println("我死了QAQ");
	}
}
public class test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		A a1=new A();
		a1=null;
		System.gc();
		System.gc();
	    try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
        }
		System.out.println("over");
}
}
//输出:
//我死了QAQ
//over

这个例子使用了延时函数,延迟了一小段时间,这样就可以看出finalize在over之前被调用了。

final修饰符都有什么作用
final修饰符可以作用在类、方法、和变量之前。
当修饰一个类时,表示这个类是一个最终类,不可以被继承。
当修饰一个方法时,表明这个方法不可被覆盖,即子类继承时不可以被重写。
当修饰一个变量时,表明这个变量不可被修改,可以认为这是一个常量。

static方法的和属性的特点
见之前的博客:
https://blog.csdn.net/qq_43791007/article/details/100623603

Application程序执行时为何不带后缀名
因为此时执行的是一个类,会自动寻找“.class”,不可以带后缀。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章