您的位置:首页 > 编程语言 > Java开发

java基础-head first java

2017-09-28 09:39 190 查看
1、问:其他程序语言都可以用整数类型做判断条件,java可以这样吗?

int x = 1;

while(x){}

答:不行,java中的integer与boolean两种类型并不相容。只能用如下的boolean变量测试。

boolean isHot = true;

while(isHot){}

2、问:在java中if与while循环都是boolean测试,有什么区别?

答:if 如果不下雨就....

while只要不下雨就...

3、产生随机数

Math.random();

4、浮点数取整

int x=(int)24.6;

5、问:编译器和虚拟机的主要作用?

答:编译器:把java文件编译成二进制的class文件;java是强类型的语言,编译器会进行类型检查,private方法检查等。

虚拟机:运行class文件,存取权限的安全问题。

6、问:面向对象的优势?

答:使用继承,可是使子类自动获得父类的功能。子类的功能可以覆盖父类,当其中一个子类变化时,不影响其他子类(面向对象设计扩展功能不需要改动之前已经测好的程序代码)。

7、问:类和对象的关系?

答:类是对象的蓝图。对象由类的模型塑造出来。在编写类时,是在描述java虚拟机应该如何制作该类型的对象。

8、java垃圾回收:创建的对象被存放在成为堆的内存区域中,不管对象如何创建都会放在此区域中。此区域并非普通的堆,它是垃圾回收的堆(Garbage-Collectible Heap)。Java会根据对象的大小来分配内存空间。当某个对象被java虚拟机察觉不再被使用到,该对象就会被标记成可回收的。如果内存开始不足,垃圾回收器就会启动清理垃圾、回收空间,让空间能够再次被利用。

9、问:需要全局变量怎么办?

答:任何变量只要加上public、static、final,基本上都会变成全局变量取用的的常数。

10、问:如果能做出全局的函数与数据,那又怎么算的上是面向对象呢?

答:首先要注意任何java中的事物都必须呆在类中。因此,pi常数或random()方法也必须定义在Math这个类中。必须要明确的是类似全局的事物在java中算是个例外,不会有多个实例或者对象。

11、问:若有成百上千的类时要如何提交?是否可以包装成类似单一应用程序的形式?

答:数量庞大的个别文件确实让用户头疼。可以把所有的文件包装依据pkzip格式来存档的Java Archive-.jar文件。在jar文件中可以引入一个简单文字格式的文字文件,它被称为mainifest,里面有定义出jar中的哪一个文件带有启动应用程序的main()方法。

12、java中的变量有两种类型:清凉的primitive主数据类型和香辣的对象引用。其中主数据类型包括整数、布尔、浮点数等。如果把分配的内存比作容器,比如杯子,那么放主数据库类型的杯子里放的是实际数值,而放对象引用的杯子里放的是指向对象的遥控器。

13、float  f = 32.6f;除非加上f,否则所有带小数的值都会被java当做double处理。

14、引用变量:所引用的对象有多大,不需关心。而引用都有相同的大小。不能对引用变量进行运算,因为“java不是c”。

15、所有的对象都生活在垃圾收集堆上。

16、方法的形参和实参。在方法定义的时候是形参,调用的时候传入的值是实参。java是通过值传递的,也就是通过拷贝传递的。

17、如果传入的参数是对象的话,那么传递的是对象的远程控制而不是对象本身,也就是传入的是远程控制的拷贝。

18、若想返回多个值,例如返回3个int,可以返回int的数组。如果是返回不同的类型,要用ArrayList。

19、封装的重要意义:比如,theCat.height=0;很显然不合理。所以要创建setter这个方法给所有的实例变量,并寻求某种方法强制其他程序都必须通过setter来设定变量而不是直接存取。比如:

//老王忘记把他的猫封装,后来他的猫就被辗平了......

public void setHeight(int ht){

if(ht>9){
height=ht;   //这个检查可以确保高度不会低于9

}

}

总之:封装会对实例变量加上绝对领域,因此没有人能够恶搞变量。比如:大部分实例变量值都有一个适当的范围,就像身高不能为负,佛跳墙不可能3分钟之内做好。

具体操作:强迫其他程序一定得经过setter。如此setter就能够检查参数并判断是否可以执行。setter也许可以退回不合理的值、或是抛出Exception、或是自己进行取小数点的动作。重点在于可以在setter中执行任何动作,而直接暴露public实体变量就不能做到。

好处:问:很多setter什么事情也没做,只是把值设给变量而已,这样会不会增加执行的负担?

答:事后可以改变想法却不会需要改变其他部分的程序。比如:一个所有人都使用的类及变量,万一有一天发现这个变量需要检查,那不是所有人都要跟着改成调用setter吗?封装的优点就是能够三心二意又不会伤害别人,直接存取变量的效率是比不上这个好处的。

20、封装的基本原则:将实例变量标记为私有的,并提供公有的getter和setter来控制存取的动作。

21、声明与初始化实例变量,int size;会有默认值,integer 0,float 0.0, booleans false,reference null。要记得引用时的null代表没有操作对象的远程控制。

但是局部变量没有默认值。

22、判断相等。使用==比较两个primitive主数据类型,或者判断两个引用是否引用同一个对象。

使用equals()来判断两个对象是否在意义上相等。

23、java API。要知道如何从通称Java API的Java的函数库中选找所需的功能,那么就不用重新发明轮子了。

24、数组和ArrayList的比较。

ArrayList在删除完一个元素之后会自动变小,而数组不能删除元素。

都是对象,但是数组没有方法,获取长度用.length实例变量,ArrayList有方法,获取长度用size()。

数组比较快,可以保存基本数据类型,arrayList保存基本类型的包装类,可以在创建的参数指定具体数据类型(包装类或是具体的类)。

数组在创建时必须指定大小,ArrayList不用,因为会在加入或删除元素中自动调整大小。

数组使用特殊的语法[ ],ArrayList是个普通对象没有特殊语法。

数组在使用时必须指定位置,ArrayList用add(int,Object)添加值,或是直接add()自行管理。

25、在删除所有元素时,数组是删除下标[0,length-1],StringBuffer可以调用自己的方法delete(0,self.length())。因为delete方法的参数遵循左开右闭原则。

26、&&  || 是短运算符,左边能得到结果就不会计算右边。& |  是长运算符,强制计算机一定要计算两边,但通常用来做位的运算。

27、关于java的API,只有java.lang包是不用声明的,其他的使用前要import包名或是用的时候写全称java.util.ArrayList。

28、java标准类库的扩展都以javax作为包名称的开头。曾经是扩展,后来转变为标准,但是名字就变不了了,毕竟很多人已经写在项目里了。

29、问:使用import会把程序变大吗?编译过程会把包或类包进去吗?

4000
答:import和C的include并不相同。运用import只是帮助省下每个类前面的包名而已,程序不会因为用了import而变大或变慢。那么那些类是怎么什么时候编译进去的呢?

30、继承里很重要的一点是,子类可以覆盖父类。而且,父类变动,没有破坏子类的话子类都不用重新编译,因为java程序只是由一堆类组成的。



31、问:所有的类都可以继承吗?类和成员一样吗标记成私有就不能继承了?

答:内部类不能继承。类没有私有的概念,但是可以不标记成公有,非公有的类只能被同一个包下的类作子类;使用final;让类只拥有private的构造函数。

32、继承的覆盖规则和多态。多态程序,编译器会寻找引用类型来决定是否可以调用该引用的方法;但在执行期,java虚拟机寻找的并不是引用所指的类型,而是堆上的对象。因此若编译器已经同意这个调用,则唯一能够通过的办法是覆盖的方法也有相同的参数和返回类型。

33、抽象类产生的最初目的:在继承中,所有的动物都可以继承自Animal类,但是这个类不能被初始化,因为不存在Animal这样的动物。现在又要有这样一个类来产生继承和多态。所以用抽象类,这样不会用来创建实例。抽象类除了被继承之外,是没有用途,没有值,没有目的的。

34、抽象类代表此类必须要被继承,抽象方法代表此方法一定要被覆盖过。抽象的类在没有特定的运行时没有任何意义,所以抽象方法写了也没有意义,抽象的方法没有内容。即在方法名后直接写分号结束。

35、抽象方法存在的意义:就算无法实现出方法的内容,但还是可以定义出一组子类型共同的协议。比如在多态中,目标就是使用父型作为方法的参数、返回类型或数组类型。通过这个机制,可以在加入新的子型到程序中,却不不必修改或重写处理这些类型的程序。即它只是为了标记出多态而存在。

36、多态的使用,ArrayList<Dog>,ArrayList<Cat>都只能存各自的种类。如果想放在一起,用ArrayList<Animal>。Animal是Dog和Cat的父型。

37、问:Object类是具体的。这跟创建Animal类一样无意义,为什么还允许创建呢?

答:因为有的时候就是会需要一个通用的对象,一个轻量化的对象。最常见的用途是在线程的同步化上。

38、接口出现的意义:不管你来自哪里,只要你实现这个接口,别人就会知道你一定会履行这个合约。

解决的问题:如果想给所有的宠物添加一个亲昵行为,直接加在所有的父型Animal中是不合适的,因为狮子等不是宠物,不需要实现这个方法。

所有接口的方法都是抽象的。

39、更重要的意义是:当你把一个类当做多态类运行时,相同的类型必须来自同一棵继承树,而且必须是该多态类型的子类,比如定义为犬科类型的参数可以接受wolf或dog,但是无法接受cat或Hippo。但是!!当用接口来作为多态类型时,对象就可以来自任何地方了,唯一的条件就是该对象必须实现来自该接口的所有方法。更棒的是,一个类可以实现多个接口!!!

常见应用:如果想要将对象的状态保存在文件中,只要去实现serializable这个接口。打算让对象的方法以单独的线程来运行,实现Runable接口。

40、问:如果判断什么时候使用设计类、子类、抽象类或是接口?

答:1)新的类无法通过is-a测试时,不能继承。2)需要某类的特殊化版本时,以覆盖或增加新方法来继承现有类。3)需要定义一群子类的模板时,又不想被初始化,使用抽象类。4)想定义出类可以扮演的角色,使用接口。

41、在java中,程序员只会在乎内存中的两种区域:对象的生存空间堆heap,方法调用及变量的生存空间栈stack。

42、实例变量和局部变量存放的位置。实例变量存在所属的对象中。局部变量和方法的参数都是被声明在方法中,他们都是暂时的,方法执行完毕声明周期结束。

43、栈顶上的方法是目前正在执行的方法。实际被堆上栈的是堆栈块,它包括执行到哪一行程序以及所有局部变量的值。

44、构造函数不会被继承。Java可以有与类同名的方法而不会变成构造函数,差别在于构造函数不会有返回类型。

45、编译器涉入构造函数的方式:1)如果没有编写构造函数

public ClassName(){

siper();

}

2)如果你有构造函数但是没有调用super(),编译器会帮你对每个重载版本的构造函数加上 super();但是!编译器帮忙加的一定会是没有参数的版本,假使父类有多个重载版本,也只有无参书的这个版本会被调用到。

46、对于super()的调用必须是构造函数的第一个语句。

47、在某个构造函数中调用重载版的另一个构造函数,使用this()。this()只能用在构造函数中,且必须是第一行语句!每个构造函数可以选择调用super()或this(),但是不能同时调用!

48、Math是不能被实例化的,因为构造函数被私有化了。

49、静态的final变量是常数。public static final double PI = 3.141592653589793;

50、final的变量代表不能改变它的值;final的method代表不能覆盖掉该方法;final的类代表不能继承该类。

51、字符串转数字:Integer.parseInt("2");    Double.perseDoubel("42.89");

数字转字符串:Integer.toString(345);

52、日期处理api,要处理当前的日期时间用Java.Util.Date,其余功能可以从Java.Util.Calendar(一个相当大的api)上面去找。

53、stream必须要连接到某处才能算是个串流。

54、序列化程序会将对象上所有的内容存储起来,包括被对象的实例变量所引用的所有对象都会被序列化。

55、如果某类是可序列化的serializable,则它的子类也自动的可以序列化(接口的本意就是如此)。

56、解序列化的时候,最后一步新的对象被分配在堆上,但构造函数不会被执行,因为这样会把对象的状态抹去又变成全新的状态,而我们想要的是对象回到存储时的状态。

57、问:静态变量会被序列化吗?

答:不会,static代表每一个类,而不是每一个对象。当对象被还原时,静态变量会维持类中原有的样子,而不是存储时的样子。

58、初步了解nio。java.nio这个类带来重大的效能提升并可以充分利用执行程序的机器上的原始容量,nio的一项关键能力是你可以直接控制buffer。另一项能力是non-blocking的输入/输出,它让你的输入/输出程序代码在没有东西可读取或写入时不必等在那里。nio使用起来更为复杂,如果没有很小心的设计,nio可能会引发效能损失。可以使用FileInputStream并通过getChannel()方法来存取channel来开始使用nio。

59、对象的锁。对象的锁只会在有同步化的方法上起作用。当对象有一个或多个同步化的方法时,线程只有在取得对象锁的钥匙才能进入同步化的方法。锁不是配在方法上,而是配在对象上。如果对象有两个同步化的方法,就表示两个线程无法进入同一个方法,也表示两个线程无法进入不同的方法。

60、如果有3个Dog对象在堆上,则总共有4个与Dog有关的锁,3个是实例的,1个是类的。当对静态的方法做同步化时,java会使用类本身的锁。

61、synchronized(this){

criticalStuff();

moreCriticalStuff();

}

把需要调用的不可分割的逻辑方法组成原子单位,这样不会将整个方法设定成需要同步化,只会使用参数所指定的对象的锁来做同步化。

62、给list<Song>排序,两种方法:1)class Song implements Comparable<Song>接口。2)在测试的类内创建内部类,由内部类实现class ArtistCompare Comparator<Song>接口,使用时调用Collections.sort(songList, artistCompare);

63、比较两个引用是否相等,用==,如果引用相同的对象,为true。

比较两个对象是否相等,用equals,而且类必须覆盖hashCode()方法和equals()方法。覆盖hashCode()方法确保两个对象有相同的hashcode,也要确保以另一个对象为参数的equals()调用会返回true。

64、equals()的默认行为是执行==比较。也就是测试两个引用是否都引用堆上的同一个对象。如果equals()没有被覆盖过,两个对象永远不会被视为相等的,因为不同的对象有不同的字节组合。如果两个对象相等,则hashcode值一定相等。原因在于hashCode()所使用的算法也许刚好会让多个对象传回相同的值,越糟糕的算法越容易碰撞。如果HashSet在比对的过程中,同样的hashcode有多个对象,会使用equals()来判断是否有完全符合的,也就是说hashcode是用来缩小寻找成本的,equals()才能确认是否真的找到相同的项目。

public boolean equals(Object aSong){

Song s = (Song) aSong;

return this.getTitle().equals(s.getTitle());

}

public int hashCode(){      //注意,hashCode()与equals()使用相同的实例变量

return titile.hashCode();

}

65、HashSet使用hashcode来大成功存取速度较快的存储方法。如果从ArrayList中寻找对象,它会从头开始找。但从HashSet中寻找,就可以通过hashcode很快的算出该对象所在的位置,而不必从头一个一个找起。

66、TreeSet会让集合处于有序的状态。如果使用默认的构造函数,会使compareTo()来排序,也可以选择传入Comparator给TreeSet的构造函数。损耗很小。

67、泛型:public void takeAnimals(ArrayList<Animal> animals) {   //这里声明的是Animal就只能传入Animal类,而不能传入它的子类

animals.add(new cat());

     }

要想使Animal和其子类都能传入,要写成public void takeAnimals(ArrayList<? extends Animal> animals) 或是 T extends Animals.

68、java程序的部署:cs,客户端服务端,服务端浏览器。

69、一旦类被放进包中,就不能用“简写”的名称来调用它,必须写出带包结构的完整名称。

70、把类放进jar包中,manifest文件中写:Main-Class: com.headfirstjava.Foo; 

用命令创建jar文件:jar -cvfm mainfest.txt  MyJar.jar  com, 即把com下所有的文件都包进jar包

用命令执行jar:java -jar MyJar.jar

71、RMI(Remote Method Invocation)远程程序调用。如下,RMI提供执行期间所需全部的基础设施,即客户端和服务端的辅助设施,也知道如果让客户端辅助设施看起来像是真正的服务(代理)。也就是,RMI知道如何提供相同的方法给客户端调用。



72、servlet:放在HTTP web服务器上面运行的java程序。

73、J2EE:Java 2 Enterprise Edition,包括Web服务器和Enterprise JavaBeans(EJB)服务器。 



74、按位异或^  :位相同时返回0,否则返回1 

int x = -11;    //位组合是11110101

右移运算符:>>,移位正负号不变         int y = x>>2;       //位组合是11111101

无符号右移:>>>,正负号可能改变         int y = x>>>2;       //位组合是00111101

左右运算符:<<,与>>>一样,但方向相反,右方补0,正负号可能改变。

75、使用局部变量,让程序扩充性更好!

76、静态嵌套类。

public class FooOuter{

static class BarInner{

void sayIt(){

System.out.println("method of a static inner class");

}

}

}

class Test{

public static void main(String[] args){

FooOuter.BarInner Foo = new FooOuter.BarInner();     //因为是静态的,所以不需要外层的实例

}

}

静态嵌套类很像一般非嵌套的,他们并未与外层对象产生特殊的关联。但因为还被认为是外层的一个成员,所以能够取外层的私有成员,当然只限于静态的成员。

77、如果考虑线程安全,应该用StringBuilder取代StringBuffer。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: