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

JAVA 基础知识

2015-12-25 20:28 423 查看


1.什么是类和对象?

EVERYTHING IS OBJECT(万物皆对象)所有的事物都有两个方面:
有什么(属性):用来描述对象。
能够做什么(方法):告诉外界对象有那些功能。
对象:对现实世界中的实体的抽象。在计算机中,是指可标识的存储区域。
类:具有共同属性和行为的对象的抽象。类是创建对象的模板。

 


2.为什么要使用面向对象?

首先,面向对象符合人类看待事物的一般规律。 对象的方法的实现细节对其他对象是屏蔽的。 我们通过类来看待对象,类是对象的抽象。

其次,采用面向对象方法可以使系统各部分各司其职、各尽所能。 对象之间的耦合性一定要低。这样才能使每个对象本身做成最好的。

对于对象的要求:高内聚、低耦合,这样容易拼装成为一个系统。

实现高内聚就是要最大限度低提高复用性(复用性好是因为高内聚)。可复用性是OOP的基础。


 


3.面向过程思想和面向对象思想比较?

面向过程的思想:由过程、步骤、函数组成,以过程为核心;

面向对象的思想:以对象为中心,先开发类,得到对象,通过对象之间相互通信实现功能。  


 


4.实例变量和局部变量的比较

实例变量:定义在类中但在任何方法之外。(New出来的均有初值)
局部变量:定义在方法之中的变量。
局部变量要先赋值,再进行运算,而实例变量均已经赋初值。这是局部变量和实例变量的一大区别。实例变量的对象赋值为null。
不允许在同一作用域内定义两个相同名称的实例变量和局部变量,但实例变量和局部变量允许命名冲突。
区分实例变量和局部变量时一定要写this。

 


5.介绍一下对构造函数的理解

构造方法是当用类生成对象时,系统在生成对象的过程中利用的方法。
注意:构造方法在生成对象的时候会被调用,但并不是构造方法生成了对象。
构造方法没有返回值。格式为:public 方法名。
构造方法的方法名与类名相同。
构造方法是在对象生成的过程中自动调用,不可能利用指令去调用。
在一个对象的生成周期中构造方法只用一次,一旦这个对象生成,那么这个构造方法失效。
注意:在对象变量中存放的是引用(地址);在简单变量中存放的是数值。
可以构造多个构造方法,但多个构造方法的参数表一定不同,参数顺序不同即属于不同的构造方法:
如果我们未给类提供一个构造方法,那么系统会自动提供一个为空的构造方法。

 


6.面向对象方法的重载(Overloading)和覆盖(Overriding)

Overloading在一个类中可以定义多个同名方法,各个方法的参数表一定不同。但修饰词可能相同,返回值也可能相同。 overloading是编译时的多态。

Overriding指子类与父类之间的同名方法,参数表顺序一定相同,但修饰符和返回值可能不同,构造函数无法覆盖。Overriding是运行时多态。  

 


7.this关键字

This表示当前对象。

特别注意:用this调用其他构造方法时,this必须为第一条语句,然后才是其他语句。  

 


8.面向对象三大特性之封装

Java中提供4个修饰符来进行对象属性和方法的访问权限控制:
private :类内部可见
default :包内部可见
protected :包内部或子类可见
public :所有可见

 


9.面向对象三大特性之继承

父类的非私有化属性和方法可以默认继承到子类。
父类的构造方法子类不可以继承,更不存在覆盖的问题。(非构造方法可以)
如果子类访问父类的构造方法,则在编译的时候提示访问不到该方法。
JAVA中不允许多继承,一个类有且只有一个父类(单继承)。
JAVA的数据结构为树型结构,而非网状。(JAVA通过接口和内部类实现多继承)
对于方法的修饰词,子类方法要比父类的方法范围更加的宽泛。父类为public,那么子类为private则出现错误。
super()表示调用父类的构造方法。super()也和this一样必须放在第一行。this()用于调用本类的构造方法。如果没有定义构造方法,那么就会调用父类的无参构造方法,即super()。

当构造一个对象的时候,系统先构造父类对象,再构造子类对象。构造一个对象的顺序:(注意:构造父类对象的时候也是这几步)
递归地构造父类对象;
顺序地调用本类成员属性赋初值语句;
本类的构造方法。

 


10.面向对象三大特性之多态

多态指的是编译时类型不变化,而运行时类型变化。 多态分两种:
编译时多态:编译时动态重载;
运行时多态:指一个对象可以具有多个类型。

 


11.修饰符static

static定义的是一块为整个类共有的一块存储区域,其发生变化时访问到的数据都是变化之后的。其变量可以通过类名去访问:类名.变量名。与实例对象访问变量为等价的。 static 可修饰属性、方法和代码块:
static修饰的属性为一个类的共享变量,属于整个类,在不实例化对象的情况下就能访问。
static修饰方法表明此方法为类方法(静态方法),静态方法不需要有对象,可以使用类名调用,静态方法不能访问非静态成员,包括成员的变量和方法,因为此时是通过类调用的,没有对象的概念。this是不可用的。
当static修饰代码块时(注:此代码块要在此类的任何一个方法之外),那么这个代码块在代码被装载进虚拟机生成对象的时候可被装载一次,以后再也不执行了,一般静态代码块被用来初始化静态成员。

一般情况下,主方法是静态方法,所以可调用静态方法,主方法为静态方法是因为它是整个软件系统的入口,而进入入口时系统中没有任何对象,只能使用类调用。 覆盖不适用于静态方法,静态方法不可被覆盖。(允许在子类中定义同名静态方法,但是没有多态,严格的讲,方法间没有多态就不能称为覆盖。  

 


12.修饰符final

final可修改类、属性、方法:
当用final修饰类的时候,此类不可被继承,即final类没有子类。这样可以用final保证用户调用时动作的一致性,可以防止子类覆盖情况的发生。
利用final修饰一个属性(变量)的时候,此时的属性成为常量。常量的地址不可改变,但在地址中保存的值(即对象的属性)是可以改变的。
利用final定义方法:这样的方法为一个不可覆盖的方法。如果在父类中有final定义的方法,那么在子类中继承同一个方法。

对于在构造方法中利用final进行赋值的时候,此时在构造之前系统设置的默认值相对于构造方法失效。 常量(这里的常量指的是实例常量:即成员变量)赋值:
在初始化的时候通过显式声明赋值。final int x=3;
在构造的时候赋值(定义时不赋值)。

局部变量可以随时赋值。 注:如果一个方法前有修饰词private或static,则系统会自动在前面加上final。即private和static方法默认均为final方法。Java中使用final和static组合,声明常量标识符(固定语法)。final并不涉及继承,继承取决于类的修饰符是否为private、default、protected还是public。也就是说,是否继承取决于这个方法对于子类是否可见。 

 


13.抽象修饰符abstract

abstract(抽象)可以修饰类、方法
如果将一个类设置为abstract,则此类不可生成对象,必须被继承使用。
abstract可以将子类的共性最大限度的抽取出来,放在父类中,以提高程序的简洁性。
abstract虽然不能生成对象,但是可以声明,作为编译时类型,但不能作为运行时类型。
final和abstract永远不会同时出现。
当abstract用于修饰方法时,此时该方法为抽象方法,此时方法不需要实现,实现留给子类覆盖,子类覆盖该方法之后方法才能够生效。
abstract和static不能放在一起,否则便会出现错误。(这是因为static不可被覆盖,而abstract为了生效必须被覆盖。)

 


14.接口和抽象类的比较

接口和抽象类都用于抽象,接口是抽象类的抽象。 接口和抽象类都不能被实例化。
接口中只有方法声明,没有实现;在接口中声明的方法具有public和abstract属性,一个类可以实现多个接口(即多继承),接口以‘,’分隔;接口中的方法必须全部实现。
抽象类可以有部分方法实现,抽象类必须通过继承才能使用。
表现目的不同:接口用来声明功能和消息,抽象类用来抽象类,达到代码复用。

 


15.内部类

注:所有使用内部类的地方都可以不用内部类,使用内部类可以使程序更加的简洁,便于命名规范和划分层次结构。内部类是一个编译时的概念,一旦编译成功,就会成为完全不同的两类。 内部类是指在一个外部类的内部再定义一个类。内部类作为外部类的一个成员,并且依附于外部类而存在的。

内部类同时具有成员和类的特性(特性不冲突)。 内部类的分类:
成员内部类
局部内部类
静态内部类
匿名内部类(图形是要用到,必须掌握)


a.成员内部类

作为外部类的一个成员存在,与外部类的属性、方法并列。

内部类和外部类的实例变量可以共存。在内部类中访问实例变量:this.属性,在内部类访问外部类的实例变量:外部类名.this.属性。

成员内部类的优点:

⑴内部类作为外部类的成员,可以访问外部类的私有成员或属性。(即使将外部类声明为PRIVATE,但是对于处于其内部的内部类还是可见的。)

⑵用内部类定义在外部类中不可访问的属性。这样就在外部类中实现了比外部类的private还要小的访问权限。

成员内部类不可以有静态属性。

建立内部类对象时应注意: 在外部类的内部可以直接使用inner s=new inner();(因为外部类知道inner是哪个类,所以可以生成对象。)而在外部类的外部,要生成(new)一个内部类对象,需要首先建立一个外部类对象(外部类可用),然后在生成一个内部类对象。

Outer outer = new Outer; Outer.Inner in=outer.new Inner();

错误的定义方式: Outer.Inner in=new Outer.Inner()。

注意:当Outer是一个private类时,外部类对于其外部访问是私有的,所以就无法建立外部类对象,进而也无法建立内部类对象。


b.局部内部类

在方法中定义的内部类称为局部内部类。与局部变量类似,在局部内部类前不加修饰符public和private,其范围为定义它的代码块。

注意:局部内部类不仅可以访问外部类实例变量,还可以访问外部类的局部变量(但此时要求外部类的局部变量必须为final)??

在类外不可直接生成局部内部类(保证局部内部类对外是不可见的)。

要想使用局部内部类时需要生成对象,对象调用方法,在方法中才能调用其局部内部类。


c.静态内部类

注意:前三种内部类与变量类似,所以可以对照参考变量,静态内部类定义在类中,任何方法外,用static定义。

静态内部类只能访问外部类的静态成员。

生成(new)一个静态内部类不需要外部类成员:这是静态内部类和成员内部类的区别。

静态内部类的对象可以直接生成:Outer.Inner in=new Outer.Inner(); 而不需要通过生成外部类对象来生成。这样实际上使静态内部类成为了一个顶级类。

静态内部类不可用private来进行定义。

注意:当类与接口(或者是接口与接口)发生方法命名冲突的时候,此时必须使用内部类来实现。用接口不能完全地实现多继承,用接口配合内部类才能实现真正的多继承。


d. 匿名内部类

匿名内部类是一种特殊的局部内部类,它是通过匿名类实现接口。

注:一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类,没有类名,根据多态,我们使用其父类名。 因其为局部内部类,那么局部内部类的所有限制都对其生效。

匿名内部类是唯一一种无构造方法类。

匿名内部类在编译的时候由系统自动起名Out$1.class。

如果一个对象编译时的类型是接口,那么其运行的类型为实现这个接口的类。因匿名内部类无构造方法,所以其使用范围非常的有限。  


 


15、运行时异常与普通异常

异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误。java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。

Throwable是所有Java程序中错误处理的父类,有两种资类:Error和Exception。
Error:表示由JVM所侦测到的无法预期的错误,由于这是属于JVM层次的严重错误,导致JVM无法继续执行,因此,这是不可捕捉到的,无法采取任何恢复的操作,顶多只能显示错误信息。
Exception:表示可恢复的例外,这是可捕捉到的。

Java提供了两类主要的异常:runtime exception和checked exception。
checked异常:也就是我们经常遇到的IO异常,以及SQL异常都是这种异常。对于这种异常,JAVA编译器强制要求我们必需对出现的这些异常进行catch。所以,面对这种异常不管我们是否愿意,只能自己去写一大堆catch块去处理可能的异常。
runtime exception,也称运行时异常,我们可以不处理。当出现这样的异常时,总是由虚拟机接管。比如:我们从来没有人去处理NullPointerException异常,它就是运行时异常,并且这种异常还是最常见的异常之一。

出现运行时异常后,系统会把异常一直往上层抛,一直遇到处理代码。如果没有处理块,到最上层,如果是多线程就由Thread.run()抛出,如果是单线程就被main()抛出。抛出之后,如果是线程,这个线程也就退出了。如果是主程序抛出的异常,那么这整个程序也就退出了。运行时异常是Exception的子类,也有一般异常的特点,是可以被Catch块处理的。只不过往往我们不对他处理罢了。也就是说,你如果不对运行时异常进行处理,那么出现运行时异常之后,要么是线程中止,要么是主程序终止。异常处理的目标之一就是为了把程序从异常中恢复出来。

 


16、Java命名规范

必须以英文字母、下划线(’_’)或’$’开始,其余可以有数字但不允许包含空格,且组合后的名称不能是Java关键字或保留字。
匈牙利命名法:以m开始为类成员变量,以g开始为全局变量,以v开始为本地局部变量,常量命名一般不以下划线、美元符开始。
驼峰命名:一般称由多个单词或缩写组成的变量名,并且该变量名每个单词首字母均为大写(一般类名全部首字母大写,方法或属性名第一个字母小写)的称为驼峰命名


一、网络编程基本概念


1.OSI与TCP/IP体系模型





 


2.IP和端口

解决了文章最开始提到的定位的问题。

IP在互联网中能唯一标识一台计算机,是每一台计算机的唯一标识(身份证);网络编程是和远程计算机的通信,所以必须先能定位到远程计算机;IP帮助解决此问题;一台计算机中可能有很多进程,具体和哪一个进程进行通信,这就得靠端口来识别;

IP和端口能唯一定位到需要通信的进程。这里的IP表示地址,区别于IP协议。在OSI体系还是TCP/IP体系中,IP协议位于网际层,来封装IP地址到报文中。 


 


3.TCP和UDP协议

TCP是Tranfer Control Protocol的简称,是一种面向连接的保证可靠传输的协议。通过TCP协议传输,得到的是一个顺序的无差错的数据流。发送方和接收方的成对的两个socket之间必须建立连接,以便在TCP协议的基础上进行通信,当一个socket(通常都是server socket)等待建立连接时,另一个socket可以要求进行连接,一旦这两个socket连接起来,它们就可以进行双向数据传输,双方都可以进行发送或接收操作。

UDP是User Datagram Protocol的简称,是一种无连接的协议,每个数据报都是一个独立的信息,包括完整的源地址或目的地址,它在网络上以任何可能的路径传往目的地,因此能否到达目的地,到达目的地的时间以及内容的正确性都是不能被保证的。

比较:

UDP:
每个数据报中都给出了完整的地址信息,因此无需要建立发送方和接收方的连接。
UDP传输数据时是有大小限制的,每个被传输的数据报必须限定在64KB之内。
UDP是一个不可靠的协议,发送方所发送的数据报并不一定以相同的次序到达接收方

TCP:
面向连接的协议,在socket之间进行数据传输之前必然要建立连接,所以在TCP中需要连接时间。
TCP传输数据大小限制,一旦连接建立起来,双方的socket就可以按统一的格式传输大的数据。
TCP是一个可靠的协议,它确保接收方完全正确地获取发送方所发送的全部数据。

数据桢:



应用:
TCP在网络通信上有极强的生命力,例如远程连接(Telnet)和文件传输(FTP)都需要不定长度的数据被可靠地传输。但是可靠的传输是要付出代价的,对数据内容正确性的检验必然占用计算机的处理时间和网络的带宽,因此TCP传输的效率不如UDP高。
UDP操作简单,而且仅需要较少的监护,因此通常用于局域网高可靠性的分散系统中client/server应用程序。例如视频会议系统,并不要求音频视频数据绝对的正确,只要保证连贯性就可以了,这种情况下显然使用UDP会更合理一些。

 


4.Socket

Socket是网络驱动层提供给应用程序编程接口和一种机制。我们可以把 Socket 比喻成是一个港口码头。应用程序只要把货物放到港口码头上,就算完成了货物的运送。对于接收方应用程序也要创建一个港口码头,只需要等待货物到达码头后将货物取走。

Socket 是在应用程序中创建的,它是通过一种绑定机制与驱动程序建立关系,告诉自己所对应的 IP 和 Port。在网络上传输的每一个数据帧,必须包含发送者的 IP 地址和端口号。创建完 Socket 以后,应用程序写入到 Socket 的数据,由 Socket 交给驱动程序向网络上发送数据,计算机从网络上收到与某个 Socket 绑定的 IP 和 Port 相关的数据后,由驱动程序再交给 Socket ,应用程序就可以从这个 Socket 中读取接收到的数据。网络应用程序就是这样通过 Socket 发送和接收的。

Socket数据发送过程:



Socket数据接收过程:

 




5.常用应用层协议

应用层协议是为了解决某一类应用问题,而问题的解决又往往是通过位于不同主机中的多个应用进程之间的通信和协同工作来完成的。应用层的具体内容就是规定应用进程在通信时所遵循的协议。

 


二、Java网络编程常用类


1.InteAddress类

Java中的InetAddress是一个代表IP地址的封装。IP地址可以由字节数组和字符串来分别表示,InetAddress将IP地址以对象的形式进行封装,可以更方便的操作和获取其属性。InetAddress没有构造方法,可以通过两个静态方法获得它的对象。

//根据主机名来获取对应的InetAddress实例
InetAddress ip = InetAddress.getByName("www.baidu.com");
//判断是否可达
System.out.println("baidu是否可达:" + ip.isReachable(2000));
//获取该InetAddress实例的IP字符串
System.out.println(ip.getHostAddress());
//根据原始IP地址(字节数组形式)来获取对应的InetAddress实例
InetAddress local = InetAddress.getByAddress(new byte[]{127,0,0,1});
System.out.println("本机是否可达:" + local.isReachable(5000));
//获取该InetAddress实例对应的全限定域名
System.out.println(local.getCanonicalHostName());




2.URL和URLConnection类

网络中的URL(Uniform Resource Locator)是统一资源定位符的简称。它表示Internet上某一资源的地址。通过URL我们可以访问Internet上的各种网络资源,比如最常见的WWW,FTP站点。 URL可以被认为是指向互联网资源的“指针”,通过URL可以获得互联网资源相关信息,包括获得URL的InputStream对象获取资源的信息,以及一个到URL所引用远程对象的连接URLConnection。 URLConnection对象可以向所代表的URL发送请求和读取URL的资源。通常,创建一个和URL的连接,需要如下几个步骤:
创建URL对象,并通过调用openConnection方法获得URLConnection对象;
设置URLConnection参数和普通请求属性;
向远程资源发送请求;
远程资源变为可用,程序可以访问远程资源的头字段和通过输入流来读取远程资源返回的信息。

这里需要重点讨论一下第三步:如果只是发送GET方式请求,使用connect方法建立和远程资源的连接即可;如果是需要发送POST方式的请求,则需要获取URLConnection对象所对应的输出流来发送请求。这里需要注意的是,由于GET方法的参数传递方式是将参数显式追加在地址后面,那么在构造URL对象时的参数就应当是包含了参数的完整URL地址,而在获得了URLConnection对象之后,就直接调用connect方法即可发送请求。而POST方法传递参数时仅仅需要页面URL,而参数通过需要通过输出流来传递。另外还需要设置头字段。以下是两种方式的代码:

//1. 向指定URL发送GET方法的请求
String urlName = url + "?" + param;
URL realUrl = new URL(urlName);
//打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
//设置通用的请求属性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
//建立实际的连接
conn.connect();
//2. 向指定URL发送POST方法的请求
URL realUrl = new URL(url);
//打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
//设置通用的请求属性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
//发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
//获取URLConnection对象对应的输出流
out = new PrintWriter(conn.getOutputStream());
//发送请求参数
out.print(param);




3.URLDecoder和URLEncoder

这两个类可以别用于将application/x-www-form-urlencoded MIME类型的字符串转换为普通字符串,将普通字符串转换为这类特殊型的字符串。使用URLDecoder类的静态方法decode()用于解码,URLEncoder类的静态方法encode()用于编码。具体使用方法如下:

//将application/x-www-form-urlencoded字符串转换成普通字符串
String keyWord = URLDecoder.decode("%E6%9D%8E%E5%88%9A+j2ee", "UTF-8");
System.out.println(keyWord);
//将普通字符串转换成  application/x-www-form-urlencoded字符串
String urlStr = URLEncoder.encode( "ROR敏捷开发最佳指南" , "GBK");
System.out.println(urlStr);




4.Socket和ServerSocket类

网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket。Socket通常用来实现客户方和服务方的连接。Socket是TCP/IP协议的一个十分流行的编程界面,一个Socket由一个IP地址和一个端口号唯一确定。 但是,Socket所支持的协议种类也不光TCP/IP一种,因此两者之间是没有必然联系的。在Java环境下,Socket编程主要是指基于TCP/IP协议的网络编程。 Server端Listen(监听)某个端口是否有连接请求,Client端向Server端发出Connect(连接)请求,Server端向Client端发回Accept(接受)消息。一个连接就建立起来了。Server端和Client端都可以通过Send,Write等方法与对方通信。
TCP Socket的通信过程如下图:



 


5.DatagramSocket类

UDP协议是一种不可靠的网络协议,它在通讯实例的两端个建立一个Socket,但这两个Socket之间并没有虚拟链路,这两个Socket只是发送和接受数据报的对象。 包java.net中提供了两个类DatagramSocket和DatagramPacket用来支持数据报通信,DatagramSocket用于在程序之间建立传送数据报的通信连接,
DatagramPacket则用来表示一个数据报。 DatagramSocket的构造方法:

DatagramSocket();
DatagramSocket(int prot);
DatagramSocket(int port, InetAddress laddr);


其中,port指明socket所使用的端口号,如果未指明端口号,则把socket连接到本地主机上一个可用的端口。laddr指明一个可用的本地地址。给出端口号时要保证不发生端口冲突,否则会生成SocketException类例外。注意:上述的两个构造方法都声明抛弃非运行时例外SocketException,程序中必须进行处理,或者捕获、或者声明抛弃。 用数据报方式编写client/server程序时,无论在客户方还是服务方,首先都要建立一个DatagramSocket对象,用来接收或发送数据报,然后使用DatagramPacket类对象作为传输数据的载体。


三、总结

网络编程的核心是IP、端口、协议三大元素
网络编程的本质是进程间通信
网络编程的2个主要问题:1是定位主机,2是数据传输
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: