分类 语言 下的文章

java内部类及四种内部类的实现方式

一、内部类定义:
内部类分为: 成员内部类、静态嵌套类、方法内部类、匿名内部类。
二、为何要内部类?
a、内部类提供了某种进入外围类的窗户。
b、也是最吸引人的原因,每个内部类都能独立地继承一个接口,而无论外围类是否已经继承了某个接口。
因此,内部类使多重继承的解决方案变得更加完整。
在项目中,需要多重继承,如果是两个接口,那么好办,接口支持多重继承。
如果是两个类呢?这时只有使用内部类了。
三、四种内部类:
1)静态内部类:
1.必须以static关键字标注
2.只能访问外部类中的静态的成员变量或者是静态的方法
3.访问一个内部类使应该这样outerClass.innerClass inter = new outerClass.innerClass();不能直接实例化内部类
2)成员内部类:
1.定义在一个类的内部,但是没有static关键字修饰
2.生成示例的方法outerClass.innerClass inter = (new outerClass()).new innerClass()
3.对外部类变量的引用outClass.this.variale
4.可以访问外部类的静态与非静态方法
3)局部内部类:
1.局部内部类指的是定义在一个方法中的类
2.只有在当前方法中才能对局部内部类里面的方法以及变量进行访问
3.局部内部类只能访问其所在方法的final类型变量
4)匿名内部类:
隐式的继承一个父类或者是实现某个接口

元组Tuple

  元组(Tuple)
  笛卡尔积中每一个元素(d1,d2,…,dn)叫作一个n元组(n-tuple)或简称元组。
  元组是关系数据库中的基本概念,关系是一张表,表中的每行(即数据库中的每条记录)就是一个元组,每列就是一个属性。 在二维表里,元组也称为记录。

Java字节流

  字节流(byte stream)   不包含边界数据的连续流   字节流是由字节组成的,字符流是由字符组成的. Java里字符由两个字节组成.字节流是最基本的,所有的InputStream和OutputStream的子类都是,主要用在处理二进制数据,它是按字节来处理的但实际中很多的数据是文本,又提出了字符流的概念,它是按虚拟机的encode来处理,也就是要进行字符集的转化。在从字节流转化为字符流时,实际上就是byte[]转化为String时,public String(byte bytes[], String charsetName)有一个关键的参数字符集编码,通常我们都省略了,那系统就用操作系统默认的lang

为什么开发者不要调用jdk中sun公司的jar包

不要引用sun开头的jar包
The java.*, javax.* and org.* packages documented in the Java 2 Platform Standard Edition API Specification make up the official, supported, public interface.
If a Java program directly calls only API in these packages, it will operate on all Java-compatible platforms, regardless of the underlying OS platform.
The sun.* packages are not part of the supported, public interface.
A Java program that directly calls into sun.* packages is not guaranteed to work on all Java-compatible platforms. In fact, such a program is not guaranteed to work even in future versions on the same platform.
Each company that implements the Java platform will do so in their own private way. The classes in sun.* are present in the SDK to support the Sun implementation of the Java platform: the sun.* classes are what make the Java platform classes work “under the covers” for the Sun Java 2 SDK. These classes will not in general be present on another vendor’s Java platform. If your Java program asks for a class “sun.package.Foo” by name, it may fail with ClassNotFoundError, and you will have lost a major advantage of developing in Java.
Technically, nothing prevents your program from calling into sun.* by name. From one release to another, these classes may be removed, or they may be moved from one package to another, and it’s fairly likely that their interface (method names and signatures) will change. (From the Sun point of view, since we are committed to maintaining the Java platform, we need to be able to change sun.* to refine and enhance the platform.) In this case, even if you are willing to run only on the Sun implementation, you run the risk of a new version of the implementation breaking your program.
In general, writing java programs that rely on sun.* is risky: they are not portable, and are not supported.
http://www.oracle.com/technetwork/java/faq-sun-packages-142232.html

JNLP介绍

一JNLP介绍:
  在java开发的早期,重点被放在了客户端开发。语言中对于applet和安全下载的支持对于万维网(WWW)的发布看上去是个不错的主意。但是现实是java最大的成功在于服务器端,java的强大功能和适应性赢得了服务器端开发者的心。同时,客户端的开发落后了。棘手的开发问题限制了applet的效用,开发者被迫转向基于浏览器的瘦客户端。
  Java Network Launching Protocol (JNLP,java网络加载协议) 承诺改变这个现状。通过JCP(Java Community Process)的JSR-56的开发, JNLP解决了很多先前用java开发针对客户端的功能的问题。一个JNLP客户端是一个应用程序或者说服务,它可以从宿主于网络的资源中加载应用程序。如果你使用JNLP打包一个应用程序,那么一个JNLP客户端能够:
  o 为该应用探测,安装并且使用正确版本的JRE(java运行时环境)
  o 从浏览器或者桌面加载应用程序
  o 当新版本的应用出现时自动下载最新的版本。
  o 为了加速启动速度在本机缓存应用程序需要的类
  o 可以作为applet或者应用程序运行
  o 在必要的情况下下载原始的库
  o 以安全的方式使用诸如文件系统这样的本机资源
  o 自动定位和加载外部依赖资源
  二JNLP文件的具体说明  
  
  
  
  
  
  
  HelloWorld
  Lively Corporation
  HelloWorld Test Example for WebStart.
  
  
  
  
  
  
  
  
  

  
  
  
  
  
  

  
  
  

  三 JNLP部署应用
  (1)编写相关应用,打包成一系列jar;
  (2)根据jnlp文件说明修改相应的jnlp内容,修改相应的url和jar;
  (3)部署jnlp文件和jar到相应的web容器;
  (4)编写访问网页,即可使用该应用〔亦可下载jnlp文件使用jws运行应用〕;
  四 补充
  如果jar需要访问本地文件资源,需要为你的jar文件签名
  先在命令行用keytool产生一个keystore文件.
  keytool -genkey -keystore you.keystore –alias youApp
  命令行用jarsigner签名,当然这时候需要生成keystore时的密码
  jarsigner -keystore you.keystore appTest.jar youApp
  重新部署即可

Java知识

1) 进制转换
整数进制转换:
10进制转换成其他的都是除以要转换成的那个数,也就是说转换成二进制的就除以2,转换成八进制的就除以8,转换成十六进制的就除以16,然后倒取余数。具体例题如下
10—2:把20转换成二进制
20/2=10……….余数为0
10/2=5………..余数为0
5/2=2…………余数为1
2/2=1…………余数为0
1/2=0…………余数为1
则20换成二进制后是10100
10—8:把20转换成八进制
20/8=2………..余数为4
2/8=0…………余数为2
则20转换成八进制后是24
10—16:把20转换成十六进制
20/16=1……….余数为4
1/16=0………..余数为1
则20转换成十六进制后是14

2—10:把二进制数1101转换成十进制
1101=1*2的0次方+0*2的1次方+1*2的2次方+1*2的3次方=13
则1101变成十进制后是13
8—10:把八进制数1340转换成十进制
1340=0*8的0次方+4*8的1次方+3*8的2次方+1*8的3次方=736
则1340变成十进制后是736
16—10:把十六进制数3A4F转换成十进制
3A4F=15*16的0次方+4*16的1次方+10*16的2次方+3*16的3次方=14927
(十六进制中的A是10,F是15)
二进制与八进制的相互转换:
八进制数 0 1 2 3 4 5 6 7
二进制数 000 001 010 011 100 101 110 111
二进制与十六进制的相互转换:
十六进制 0 1 2 3 4 5 6 7 B
二进制数 0000 0001 0010 0011 0100 0101 0110 0111 1011
十进制小数进制转换:
用的通俗易懂的说法:用这个小数不断乘2,直到这个小数变为整数后,然后这个整数就转为二进制了,接着,刚才乘了几次2,你就把这个二进制的小数点像坐移几位即可
例:0.75
0.75X2=1.5
1.5X2=3
得到整数3,现在把3转为二进制,如下:
3(10)=》11(2)
得到二进制数:11
因为刚才乘了2次“2”,所以小数像左易懂2位,最终结果:0.11
有些小数乘2是永得不到整数的,那就看他要求的精度,假如要求保留3位小数,则乘3次“2”即可,后面的小数可以无视,直接拿直面的整数部分转为二进制,再向左移3位.
如此类推….
2) java基础数据类型
实数:double、float
整数:byte、short、int、long
字符:char
布尔值:boolean
int:int为整数类型,在存储的时候,用4个字节存储,范围为-2,147,483,648到2,147,483,647,在变量初始化的时候,int类型的默认值为0。
short:short也属于整数类型,在存储的时候,用2个字节存储,范围为-32,768到32,767,在变量初始化的时候,short类型的默认值为0,一般情况下,因为Java本身转型的原因,可以直接写为0。
long:long也属于整数类型,在存储的时候,用8个字节存储,范围为-9,223,372,036,854,775,808到9,223,372,036, 854,775,807,在变量初始化的时候,long类型的默认值为0L或0l,也可直接写为0。
byte:byte同样属于整数类型,在存储的时候,用1个字节来存储,范围为-128到127,在变量初始化的时候,byte类型的默认值也为0。
float:float属于实数类型,在存储的时候,用4个字节来存储,范围为32位IEEEE 754单精度范围,在变量初始化的时候,float的默认值为0.0f或0.0F,在初始化的时候可以写0.0。
double:double同样属于实数类型,在存储的时候,用8个字节来存储,范围为64位IEEE 754双精度范围,在变量初始化的时候,double的默认值为0.0。
char:char属于字符类型,在存储的时候用2个字节来存储,因为Java本身的字符集不是用ASCII码来进行存储,是使用的16位Unicode字符集,它的字符范围即是Unicode的字符范围,在变量初始化的时候,char类型的默认值为’u0000’。
boolean:boolean属于布尔类型,在存储的时候不使用字节,仅仅使用1位来存储,范围仅仅为0和1,其字面量为true和false,而boolean变量在初始化的时候变量的默认值为false。

java基础数据类型

java基础数据类型


3) 类、接口、抽象类(需要继续深入推敲和理解)
大家也许都知道做工艺器或是工厂里做生产某些产品的模具模具。如做一个金属的五角星,只要将钢水罐到五角星的模具模具里就可以很容易地制做五角星。
我们也可以将类比喻成做五角星的模具。 而生产出的一个个五角星就是一个个对象。 为了建立不同的对象(有的是金属的、有的塑料的,等等),可通过向模具里灌入不同的液态材料就可以制做。这也相当于向类的构造方法中传入不同的参数(相当于不同的液态材料)。
还有就是接口,如果说类是对象的抽象,那么接口就是类的抽象。
我们也可以将接口看成是制做这个五角星模具的规格列表(相当于接口中的抽象方法)。也就是说,只有这个模具(类)符合(实现)相应的规格(接口),才会成为制做五角星的模具模具。
哈哈,当然,这个使用模具生成五角星及其他产品的工厂可以看成是对象工厂。
也就是说,类和接口都不是实际的产品,都不能拿来用,类相当于模具(没人会拿模具模具在商店里卖吧,估计只有对象工厂会买),而接口只相当于制做模具的规格列表,如尺寸、角度等。而这些规格列表的内容需要在具体类中实现才可能成为具体的模具,如长度和宽度,如果在类中实现为长度等于宽度,那么这个类就成为一个成方形的模具,如果长度不等于宽度,就是一个长方形的模具。然后再实例化这个模具(类),就生成出一个个正方形或长方形对象。
在面向对象理论中还有一个抽象类,这个抽象类其实就相当于一个半成品的模具。如只实现在长度和宽度(相当于在抽象类中已实现的方法),并没有实现深度(这个深度相当于抽象类中的抽象方法,这个抽象方法需要在抽象类的子类中实现)。所以这个模具就是半成品了。因此,是无法直接拿半成品的模具(抽象类)去生产(实例化)产品(对象)的。

java方法的参数传递机制

基本类型作为参数传递时,是传递值的拷贝,无论你怎么改变这个拷贝,原值是不会改变的。
在Java中对象作为参数传递时,是把对象在内存中的地址拷贝了一份传给了参数。

java中只有值传递,基本类型变量值就是本身,引用变量值是地址
数组是对象,字符串为对象。

什么是开闭原则

软件系统中包含的各种组件,例如模块(Modules)、类(Classes)以及功能(Functions)等等,应该在不修改现有代码的基础上,引入新功能。开闭原则中“开”,是指对于组件功能的扩展是开放的,是允许对其进行功能扩展的;开闭原则中“闭”,是指对于原有代码的修改是封闭的,即不应该修改原有的代码。
☆ 开闭原则指的是一个软件实体应对对扩展开发,对修改关闭(Software entities should be open for extension, but closed for modification)。这个原则是说在设计一个模块的时候,应对使这个模块可以在不被修改的前提下被扩展,换言之,应对可以不必修改源代码的情况下改变这个模块的行为。
☆ 满足开闭原则的软件系统的优越性:
① 通过扩展已有的软件系统,可以提供新的行为,以满足对软件的新需求,使变化中的软件系统有一定的适应性和灵活性。
② 已有的软件模块,特别是最重要的抽象层模块不能再修改,这就使变化中的软件系统有一定的稳定性和延续性。
ξ4.2 实现开闭原则的关键
抽象化是解决问题的关键,在面向对象的编程语言里,可以给系统定义出一套相对较为固定的抽象设计,此设计允许无穷无尽的行为在实现层被实现。在语言里,可以给出一个或多个抽象类或者接口,规定出所有的具体类必须提供的方法的特征作为系统设计的抽象层。这个抽象层预见了所有的可扩展性,因此,在任何扩展情况下都不会改变。这就使得系统的抽象不需要修改,从而满足了开闭原则的第二条,对修改关闭。
同时,由于从抽象层导出一个或多个新的具体类可以改变系统的行为,因此系统的设计对扩展是开放的,这就满足了开闭原则的第一条。
☆ 对可变性的封装原则
这是对开闭原则的另外一种描述,它讲的是找到一个系统的可变因素,将之封装起来。该原则意味着两点:
① 一种可变性不应当散落在代码的很多角落,而应当封装到一个对象里面。继承应当被看做是封装变化的方法,而不应该被认为是一种从一般对象生成特殊对象的方法。
② 一种可变性不应当与另外一种可变性混合在一起。这意味着一般的继承层次不会超过两层。
关键知识点:
☆ 开闭原则的概念,软件实体对扩展开发,对修改关闭;
☆ 实现开闭原则的关键,利用接口或抽象类抽象出系统的抽象层,抽象层不变,利用实现层进行扩展;
☆ 对可变性的封装,将可变的元素封装起来,防止改变扩散到整个应用;
☆ 注意控制封装的粒度,不要将两种可变性封装到一起;
☆ 继承是用来封装可变性的,一般的继承层次不要超过两层;
☆ 策略模式是对开闭原则的很好诠释,其他还有工厂模式、建造模式、桥接模式、门面模式、调停者模式、访问者模式和迭代子模式等;
☆ 对“将条件转移语句改写成多态性”的重构行为应当遵循开闭原则,防止多态性污染;
☆ java下的单方法接口通常用来实现函数指针或者委托的功能;
☆ 任何一棵继承树都要以抽象类为根,具体类不是用来继承的,更不要从工具类继承;
☆ 抽象类要拥有尽可能多的共同代码,同时拥有尽可能少的数据。
☆ 当Coad条件全部满足时,才应当考虑使用继承:派生类是基类的一个特殊种类,而不是其的一个角色,也就是说要区分“Has-a”和“Is-a”;永远不会出现需要将派生类换成另外一个类的派生类的情况;派生类具有扩展基类的责任而不是具有置换或注销基类的责任;只有在分类学角度上有意义时,才可以使用继承。

Java异常处理

进行架构设计时,回避不了异常这个技术点,如何决定抛出哪种异常?
如果调用者可以为这个异常做些什么,那么就应该抛出被检查异常,否则最好是使用运行时异常。例如:FileNotFoundException是一个被检查异常,大多数时候,调用者可能做一些事情来处理这个问题;NullPointerException是一个无须检查的运行时异常,不仅因为它通常是致命的,还因为它可能在程序执行的任何时刻发生。