Java Console Input

Java Console Input import java.io.Console; public class ConsoleInput { public static void main(String[] args) { Console console = System.console(); String titleUser = "Please enter value"; String label = "[Encrypted value]:"; String titlePWD = "password:"; String description = "Please enter a Digit:: 0: Start encrypt words 1: Exit"; String flag ="0"; if(console!=null){ while("0".equals(flag.trim())) { String srcWord = console.readLine("[%s]:", titleUser); console.printf("%s", label + srcWord); console.flush(); System.out.println(); System.out.println(description); flag =console.readLine(); System.out.println(); char[] password = console.readPassword("[%s]", titlePWD); String strPassword = String.valueOf(password); java.util.Arrays.fill(password, '*'); console.printf("%s", titlePWD + String.valueOf(password)); console.flush(); System.out.println(); } } } }

2012-09-26 · 1 min · 89 words · lcf

Java

Java Java,是由_Sun Microsystems_公司于1995年5月推出的Java程序设计语言和Java平台的总称。用Java实现的HotJava浏览器 (支持Java applet) 显示了Java的魅力: 跨平台、动态的Web、Internet计算。从此,Java被广泛接受并推动了Web的迅速发展,常用的浏览器现在均支持Java applet。 1995年5月23日,Java语言诞生 1996年1月,第一个JDK-JDK1.0诞生 1996年4月,10个最主要的操作系统供应商申明将在其产品中嵌入JAVA技术 1996年9月,约8.3万个网页应用了JAVA技术来制作 1997年2月18日,JDK1.1发布 1997年4月2日,JavaOne会议召开,参与者逾一万人,创当时全球同类会议规模之纪录 1997年9月,JavaDeveloperConnection社区成员超过十万 1998年2月,JDK1.1被下载超过2,000,000次 1998年12月8日,JAVA2企业平台J2EE发布 1999年6月,SUN公司发布Java的三个版本: 标准版 (J2SE) 、企业版 (J2EE) 和微型版 (J2ME) 2000年5月8日,JDK1.3发布 2000年5月29日,JDK1.4发布 2001年6月5日,NOKIA宣布,到2003年将出售1亿部支持Java的手机 2001年9月24日,J2EE1.3发布 2002年2月26日,J2SE1.4发布,自此Java的计算能力有了大幅提升 2004年9月30日18:00PM,J2SE1.5发布,成为Java语言发展史上的又一里程碑。为了表示该版本的重要性,J2SE1.5更名为Java SE 5.0 2005年6月,JavaOne大会召开,SUN公司公开Java SE 6。此时,Java的各种版本已经更名,以取消其中的数字"2": J2EE更名为Java EE,J2SE更名为Java SE,J2ME更名为Java ME 2006年12月,SUN公司发布JRE6.0 2009年12月,SUN公司发布Java EE 6 2010年11月,由于Oracle公司对于Java社区的不友善,因此Apache扬言将退出JCP[7] 2011年7月28日,Oracle公司发布Java SE 7 一、算术运算符: 单目: + (取正) - (取负) ++ (自增1) - - (自减1) 双目: + - * / % (取余) 三目: a>b?true:false 说明: 当a大于b的时候,为true (也就是冒号之前的值) ,否则为false;这整个运算符包括一个关系运算符 (可以是">""<""!=“等等) ,一个”?",一个": “,冒号前后需要有两个表达式或者是值或者是对象。 ...

2012-09-26 · 1 min · 189 words · -

Java 数据对象 JDO,JDBC

Java 数据对象 JDO,JDBC http://developer.51cto.com/art/200510/6932.htm 介绍 Java 数据对象 (JDO) is 是一个存储Java对象的规范. 它已经被JCP组织定义成JSR12规范。JDO的第一个版本在2000年6月6日提交并在2002年4月30日正式发布1.0版本规范。规范的两个主要目的是提供数据处理和访问机制的API以及允许规范的实现作为应用服务器的一部分。 JDO 和 JDBC JDBC和JDO都是Java调用数据库的APIs。区别在于,他们访问数据存储的具体方法不同。JDBC提供了一种非常好的机制,它可以使应用程序代码与具体的数据库厂商和数据库位置无关。在大多数情况下数据存储使用的是关系数据库。但是当使用JDBC驱动运行在一个非关系数据库时就不是很好了。而对于JDO来说,运行在它之下的数据库就可以是一个关系数据库,面向对象的数据库或者其他完全不同的数据库。在JDO运行于关系数据库之上时,它可以通过JDBC很好的完成数据存储。而这一切对于开发人员来说都是透明的,所有实现都有JDO本身来完成。 JDBC不支持面向对象的数据库表示。JDBC数据库表示完全围绕关系数据库模型。这常常导致书写代码时在应用程序和数据库之间存在一个中间层。这个层的作用也许是分解Java对象。分解Java对象的过程会对使用的对象稍作改变,这样对象才能存储到关系数据库之中。同样的必须存在一种机制来把数据库中的记录转换成适当的Java对象。JDO与JDBC刚好相反,他的数据库标示完全面向对象。这种机制并不新奇,在一些面向对象数据库中已经使用了这种机制。 JDBC的查询语言一般都是用SQL。JDO的查询语言看起来与Java更接近。使用JDO无需再专门学习一种查询语言比如SQL。如果你会用Java那么你就能够使用JDO的查询语言。 执行 JDO规范定义了JDO实现的接口已经JDO实现的内容。SUN提供了一个JDO规范的参考实现,但是在2002年5月份发布的版本中它并没有完全实现规范中所要求的内容。还有众多的厂商提供的JDO实现可以使用。在下面的表格中列出了一部分。 厂商 产品 SolarMetric Kodo JDO PrismTech OpenFusion Java Data Objects Signsoft intelliBO Poet FastObjects API

2012-09-25 · 1 min · 34 words · -

Collection List Set Map 区别

Collection List Set Map 区别 这些都代表了Java中的集合,这里主要从其元素是否有序,是否可重复来进行区别记忆,以便恰当地使用,当然还存在同步方面的差异,见上一篇相关文章。 有序否 允许元素重复否 Collection 否 是 List 是 是 Set 是 是 HashSet TreeSet 是 (用二叉树排序) Map AbstractMap 否 HashMap 是 (用二叉树排序) http://tb.blog.csdn.net/TrackBack.aspx?PostId=584112 List接口对Collection进行了简单的扩充,它的具体实现类常用的有ArrayList和LinkedList。你可以将任何东西放到一个List容器中,并在需要时从中取出。ArrayList从其命名中可以看出它是一种类似数组的形式进行存储,因此它的随机访问速度极快,而LinkedList的内部实现是链表,它适合于在链表中间需要频繁进行插入和删除操作。在具体应用时可以根据需要自由选择。前面说的Iterator只能对容器进行向前遍历,而ListIterator则继承了Iterator的思想,并提供了对List进行双向遍历的方法。 Set接口也是Collection的一种扩展,而与List不同的时,在Set中的对象元素不能重复,也就是说你不能把同样的东西两次放入同一个Set容器中。它的常用具体实现有HashSet和TreeSet类。HashSet能快速定位一个元素,但是你放到HashSet中的对象需要实现hashCode()方法,它使用了前面说过的哈希码的算法。而TreeSet则将放入其中的元素按序存放,这就要求你放入其中的对象是可排序的,这就用到了集合框架提供的另外两个实用类Comparable和Comparator。一个类是可排序的,它就应该实现Comparable接口。有时多个类具有相同的排序算法,那就不需要在每分别重复定义相同的排序算法,只要实现Comparator接口即可。集合框架中还有两个很实用的公用类: Collections和Arrays。Collections提供了对一个Collection容器进行诸如排序、复制、查找和填充等一些非常有用的方法,Arrays则是对一个数组进行类似的操作。 Map是一种把键对象和值对象进行关联的容器,而一个值对象又可以是一个Map,依次类推,这样就可形成一个多级映射。对于键对象来说,像Set一样,一个Map容器中的键对象不允许重复,这是为了保持查找结果的一致性;如果有两个键对象一样,那你想得到那个键对象所对应的值对象时就有问题了,可能你得到的并不是你想的那个值对象,结果会造成混乱,所以键的唯一性很重要,也是符合集合的性质的。当然在使用过程中,某个键所对应的值对象可能会发生变化,这时会按照最后一次修改的值对象与键对应。对于值对象则没有唯一性的要求。你可以将任意多个键都映射到一个值对象上,这不会发生任何问题 (不过对你的使用却可能会造成不便,你不知道你得到的到底是那一个键所对应的值对象) 。Map有两种比较常用的实现: HashMap和TreeMap。HashMap也用到了哈希码的算法,以便快速查找一个键,TreeMap则是对键按序存放,因此它便有一些扩展的方法,比如firstKey(),lastKey()等,你还可以从TreeMap中指定一个范围以取得其子Map。键和值的关联很简单,用pub(Object key,Object value)方法即可将一个键与一个值对象相关联。用get(Object key)可得到与此key对象所对应的值对象。 http://zhidao.baidu.com/question/16113509.html

2012-09-25 · 1 min · 39 words · lcf

Java 流, Stream

Java 流, Stream IO流的分类: 根据流的数据对象来分: 高端流: 所有的内存中的流都是高端流,比如: InputStreamReader 低端流: 所有的外界设备中的流都是低端流,比如InputStream,OutputStream 如何区分: 所有的流对象的后缀中包含Reader或者Writer的都是高端流,反之,则基本上为低端流,不过也有例外,比如PrintStream就是高端流 根据数据的流向来分: 输出流: 是用来写数据的,是由程序 (内存) ->外界设备 输入流: 是用来读数据的,是由外界设备->程序 (内存) 如何区分: 一般来说输入流带有Input,输出流带有Output 根据流数据的格式来分: 字节流: 处理声音或者图片等二进制的数据的流,比如InputStream 字符流: 处理文本数据 (如txt文件) 的流,比如InputStreamReader 如何区分: 可用高低端流来区分,所有的低端流都是字节流,所有的高端流都是字符流 根据流数据的包装过程来分: 原始流: 在实例化流的对象的过程中,不需要传入另外一个流作为自己构造方法的参数的流,称之为原始流。 包装流: 在实例化流的对象的过程中,需要传入另外一个流作为自己构造方法发参数的流,称之为包装流。 如何区分: 所以的低端流都是原始流,所以的高端流都是包装流 流是 Java 中最重要的基本概念之一。文件读写、网络收发、进程通信,几乎所有需要输入输出的地方,都要用到流。 流是做什么用的呢?就是做输入输出用的。为什么输入输出要用"流"这种方式呢?因为程序输入输出的基本单位是字节,输入就是获取一串字节,输出就是发送一串字节。但是很多情况下,程序不可能接收所有的字节之后再进行处理,而是接收一点处理一点。比方你下载魔兽世界,不可能全部下载到内存里再保存到硬盘上,而是下载一点就保存一点。这时,流这种方式就非常适合。 在 Java 中,每个流都是一个对象。流分为两种: 输入流(InputStream)和输出流(OutputStream)。对于输入流,你只要从流当中不停地把字节取出来就是了;而对于输出流,你只要把准备好的字节串传给它就行。 __Java 程序 | | 外部系统 –|–(输入流)–> 处理逻辑 –(输出流)—|–> 外部系统 |_________________________________| 流对象是怎么获得的呢?不同的外部系统,获取流的方式也不同。例如,文件读写就要创建 FileInputStream/FileOutputStream 对象,而网络通信是通过 Socket 对象来获取输入输出流的。一般来说,如果一个类有 getInputStream() 或 getOutputStream() 这样的方法,就表明它是通过流对象来进行输入输出的。 InputStream 是输入流,下面是一个通过 InputStream 读取文件的例子: import java.io.File; ...

2012-09-25 · 3 min · 635 words · lcf

stop() 和 suspend() 方法为何不推荐使用?

stop() 和 suspend() 方法为何不推荐使用? http://blog.csdn.net/yakihappy/article/details/3979912 反对使用stop(),是因为它不安全。它会解除由线程获取的所有锁定,当在一个线程对象上调用stop()方法时,这个线程对象所运行的线程就会立即停止,假如一个线程正在执行: synchronized void { x = 3; y = 4;}由于方法是同步的,多个线程访问时总能保证x,y被同时赋值,而如果一个线程正在执行到x = 3;时,被调用了 stop()方法,即使在同步块中,它也干脆地stop了,这样就产生了不完整的残废数据。而多线程编程中最最基础的条件要保证数据的完整性,所以请忘记线程的stop方法,以后我们再也不要说"停止线程"了。而且如果对象处于一种不连贯状态,那么其他线程能在那种状态下检查和修改它们。结果 很难检查出真正的问题所在。 suspend()方法容易发生死锁。调用suspend()的时候,目标线程会停下来,但却仍然持有在这之前获得的锁定。此 时,其他任何线程都不能访问锁定的资源,除非被"挂起"的线程恢复运行。对任何线程来说,如果它们想恢复目标线程,同时又试图使用任何一个锁定的资源,就 会造成死锁。所以不应该使用suspend(),而应在自己的Thread类中置入一个标志,指出线程应该活动还是挂起。若标志指出线程应该挂起,便用 wait()命其进入等待状态。若标志指出线程应当恢复,则用一个notify()重新启动线程。

2012-09-25 · 1 min · 23 words · lcf

corba, ejb, webservice, rest分布式 区别

corba, ejb, webservice, rest分布式 区别 Corba,还是EJB,都有一些共同点: 通过专有的网络协议通讯 不能跨平台调用 通过分布式对象调用来实现分布式架构,换句话来说就是,分布式架构是绑定在面向对象的机制上的 分布式对象架构的缺陷在EJB2时代被充分暴露了出来 web services有一些明显不同于Corba和EJB分布式对象架构的特征: 通过标准SOAP协议通讯,一般走HTTP通道 能够跨平台调用 通讯格式是xml文本,而不是二进制数据格式 通过RPC机制来实现分布式调用,而不是通过面向对象机制实现分布式调用 REST也是一种分布式系统的架构风格,那么REST和上面这些分布式架构有哪些明显的区别呢? REST走的是HTTP协议,并且充分利用或者说极端依赖HTTP协议 Corba和EJB是采用专有的二进制协议,SOAP可以但不依赖HTTP,并且仅仅使用HTTP POST。 REST是基于HTTP抽象资源的分布式调用,换句话来说,就是分布式调用是绑定在资源的操作上面的。 分布式架构 协议 调用方式 Corba架构 专有二进制协议 对象的CRUD操作 EJB架构 专有二进制协议 对象的CRUD操作 Web Services SOAP协议 RPC方式 REST HTTP协议 对资源的CRUD操作 REST最大的特点是什么呢?REST是为通过HTTP协议来进行分布式调用量身定造的架构 REST是专门为分布式调用设计的架构,在REST里面,分布式是通过对资源的操作来实现的,不是像EJB那样通过对象的方法调用来实现的。资源是一种抽象的概念,资源被映射到相应的一套URL规则上面了。所以资源只和URL相关,而与具体实现无关,因此REST具有更好的解藕性。

2012-09-25 · 1 min · 39 words · lcf

XML Schema, XML DTD

XML Schema, XML DTD http://www.ibm.com/developerworks/cn/xml/x-sd/index.html 引言 XML DTD(XML的文档类型定义)是近几年来XML技术领域所使用的最广泛的一种模式。但是,由于XML DTD并不能完全满足XML自动化处理的要求,例如不能很好实现应用程序不同模块间的相互协调,缺乏对文档结构、属性、数据类型等约束的足够描述等等,所以W3C于2001年5月正式推荐XML Schema为XML 的标准模式。显然,W3C希望以XML Schema来作为XML模式描述语言的主流,并逐渐代替XML DTD。那么XML Schema与XML DTD相比到底有哪些优势呢,XML DTD是否真的会在XML的模式描述领域中逐渐消失呢? 回页首 XML模式与XML格式 XML模式是指用来描述XML结构、约束等因素的语言,例如XML Schema、XML DTD、XDR,SOX等等。XML格式则是XML文档本身所具有的格式。本文以XML Schema来代表W3C所推荐的XML Schema模式标准,而以"XML模式"来代表所有的XML模式描述语言。 从模式的描述语言来说,XML Schema和XML DTD都属于语法模式。与概念模式不同,语法模式在对同一事物描述时,可以采用不同的语法,例如在对关系模式描述时,无论是使用XML Schema还是XML DTD,都既可以用元素也可以用属性来描述关系模式的列。 模式必须以某种格式来表示,XML Schema的格式与XML DTD的格式有着非常明显的区别,XML Schema事实上也是XML的一种应用,也就是说XML Schema的格式与XML的格式是完全相同的,而作为SGML DTD的一个子集,XML DTD具有着与XML格式完全不同的格式。这种区别会给XML Schema的使用带来许多好处: XML用户在使用XML Schema的时候,不需要为了理解XML Schema而重新学习,节省了时间; 由于XML Schema本身也是一种XML,所以许多的XML编辑工具、API 开发包、XML语法分析器可以直接的应用到XML Schema,而不需要修改。 作为XML的一个应用,XML Schema理所当然的继承了XML的自描述性和可扩展性,这使得XML Schema 更具有可读性和灵活性。 由于格式完全与XML一样,XML Schema除了可以像XML一样处理外,也可以同它所描述的XML文档以同样的方式存储在一起,方便管理。 XML Schema与XML格式的一致性,使得以XML为数据交换的应用系统之间,也可以方便的进行模式交换。 XML有非常高的合法性要求,XML DTD对XML的描述,往往也被用作验证XML合法性的一个基础,但是XML DTD本身的合法性却缺少较好的验证机制,必需独立处理。XML Schema则不同,它与XML有着同样的合法性验证机制。

2012-09-25 · 1 min · 55 words · lcf

Synchronized 和 java.util.concurrent.locks.Lock 的区别

Synchronized 和 java.util.concurrent.locks.Lock 的区别 主要相同点: Lock 能完成 Synchronized 所实现的所有功能。 主要不同点: Lock 有比 Synchronized 更精确的线程语义和更好的性能。Synchronized 会自动释放锁,但是 Lock 一定要求程序员手工释放,并且必须在 finally 从句中释放。 synchronized 修饰方法 synchronized 修饰方法时 表示同一个对象在不同的线程中表现为同步队列 如果实例化不同的对象 那么synchronized就不会出现同步效果了。 对象的锁 所有对象都自动含有单一的锁。 JVM负责跟踪对象被加锁的次数。如果一个对象被解锁,其计数变为0。在任务 (线程) 第一次给对象加锁的时候,计数变为1。每当这个相同的任务 (线程) 在此对象上获得锁时,计数会递增。 只有首先获得锁的任务 (线程) 才能继续获取该对象上的多个锁。 每当任务离开一个 synchronized 方法,计数递减,当计数为0的时候,锁被完全释放,此时别的任务就可以使用此资源。 synchronized同步块 2.1同步到单一对象锁 当使用同步块时,如果方法下的同步块都同步到一个对象上的锁,则所有的任务 (线程) 只能互斥的进入这些同步块。 Resource1.java演示了三个线程 (包括main线程) 试图进入某个类的三个不同的方法的同步块中,虽然这些同步块处在不同的方法中,但由于是同步到同一个对象 (当前对象 synchronized (this)) ,所以对它们的方法依然是互斥的。 比如 Class Test{ public static User user=null; Public synchronized void add(User u){ user=u; Dao.save(user) } } //如果在线程1中 Test test=new Test(); User u=new User(); u.setUserName("liaomin"); u.setUserPassword("liaomin"); Test.add(u); //如果在线程2中 Test tes1t=new Test(); User u1=new User(); u1.setUserName("huqun"); u1.setUserPassword("huqun"); Tes1t.add(u1); 那么 现在线程1 和线程2同时启动 如果对象new的不是同一个Test ...

2012-09-25 · 1 min · 158 words · lcf

Java Thread/线程

Java Thread/线程 java的线程是映射到操作系统原生线程之上的 java线程阻塞的代价 java的线程是映射到操作系统原生线程之上的,如果要阻塞或唤醒一个线程就需要操作系统介入,需要在户态与核心态之间切换,这种切换会消耗大量的系统资源,因为用户态与内核态都有各自专用的内存空间,专用的寄存器等,用户态切换至内核态需要传递给许多变量、参数给内核,内核也需要保护好用户态在切换时的一些寄存器值、变量等,以便内核态调用结束后切换回用户态继续工作。 如果线程状态切换是一个高频操作时,这将会消耗很多CPU处理时间; 如果对于那些需要同步的简单的代码块,获取锁挂起操作消耗的时间比用户代码执行的时间还要长,这种同步策略显然非常糟糕的。 线程状态 线程共包括以下5种状态。 新建状态 (New): 线程对象被创建后,就进入了新建状态。例如,Thread thread = new Thread()。 就绪状态(Runnable): 也被称为 “可执行状态”。线程对象被创建后,其它线程调用了该对象的start()方法,从而来启动该线程。例如,thread.start()。处于就绪状态的线程,随时可能被CPU调度执行。 运行状态(Running): 线程获取CPU权限进行执行。需要注意的是,线程只能从就绪状态进入到运行状态。 阻塞状态(Blocked): 阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种: 等待阻塞 – 通过调用线程的 wait() 方法,让线程等待某工作的完成。 同步阻塞 – 线程在获取 synchronized 同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态。 其他阻塞 – 通过调用线程的 sleep() 或 join() 或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。 死亡状态(Dead): 线程执行完了或者因异常退出了run()方法,该线程结束生命周期。 这 5 种状态涉及到的内容包括 Object 类, Thread 类, 和 synchronized 关键字。 这些内容我们会在后面的章节中逐个进行学习。 Object 类,定义了 wait(), notify(), notifyAll( ) 等休眠/唤醒函数。 Thread 类,定义了一些列的线程操作函数。例如,sleep() 休眠函数, interrupt() 中断函数, getName() 获取线程名称等。 synchronized,是关键字;它区分为 synchronized 代码块和 synchronized 方法。 synchronized 的作用是让线程获取对象的同步锁。 在后面详细介绍 wait(), notify() 等方法时,我们会分析为什么 “wait(), notify() 等方法要定义在 Object 类,而不是 Thread 类中” ...

2012-09-22 · 4 min · 849 words · -

ultra mobile

ultra mobile 换手机之后给手机写入 eSIM ultra mobile 用手机号和密码登录 切换到 ACCOUNT My SIM> Change Device Get an eSIM This is my new device 选择 我有 wifi 连接 然后需要等一段时间会自动切换掉安装 eSIM 页面

2012-09-22 · 1 min · 28 words · -

postgresql json jsonb

jpostgresql json jsonb postgresql—-JSON类型和函数 postgresql支持两种json数据类型:json和jsonb,而两者唯一的区别在于效率,json是对输入的完整拷贝,使用时再去解析,所以它会保留输入的空格,重复键以及顺序等。而jsonb是解析输入后保存的二进制,它在解析时会删除不必要的空格和重复的键,顺序和输入可能也不相同。使用时不用再次解析。两者对重复键的处理都是保留最后一个键值对。效率的差别:json类型存储快,使用慢,jsonb类型存储稍慢,使用较快。 注意:键值对的键必须使用双引号 从PostgreSQL 9.3开始,json就成了postgres里的一种数据类型,也就是和varchar、int一样,我们表里的一个字段的类型可以为json了。 与此同时,postgres还提供了jsonb格式,jsonb格式是json的二进制形式,二者的区别在于json写入快,读取慢,jsonb写入慢,读取快,但在操作上,二者是没有区别的。下面以jsonb为例。 创建表 假设我们要存储的json数据是这样的: { “id”: ID “name”:“名字”, “age”:年龄 } 建表语句如下: create table if not exists name_age ( info jsonb ) 好了,这样就创建了一张表,里面只有一个 info 字段,下面开始进行CRUD操作。 插入数据 插入数据可以直接以json格式插入: insert into name_age values(’{“id”:1,“name”:“小明”, “age”:18}’) 在json里插入新的key值gender,如下: SELECT info||’{“gender”:“男”}’::jsonb from name_age where (info-»‘id’)::int4 = 1 查询数据 Postgres里的查询需要用到查询符。比如说,我们要查询id为1的数据,语句如下: select info from name_age where info @> ‘{“id”:1}’::jsonb 用到了 @> 这个查询符,表明info当前这条记录里的顶层json中有没有id为1的key-value对;有的话则满足条件。 再来一个复杂一点的查询的,查询 age>16 的记录,并且只显示 name ,语句如下: select info->‘name’ from name_age where (info-»‘age’)::int4 > 16 关于详细运算符使用,请参考官方文档: 9.15. JSON Functions and Operators ...

2012-09-22 · 4 min · 716 words · -

java hashcode

java hashcode java hash code hash code是一种编码方式,在Java中,每个对象都会有一个hashcode,Java可以通过这个hashcode来识别一个对象。至于hashcode的具体编码方式,比较复杂 (事实上这个编码是可以由程序员通过继承和接口的实现重写的) ,可以参考数据结构书籍。而hashtable等结构,就是通过这个哈希实现快速查找键对象。这是他们的内部联系,但一般编程时无需了解这些,只要知道hashtable实现了一种无顺序的元素排列就可以了。 两个对象值相同(x.equals(y) == true),则一定有相同的hash code。 因为: Hash,一般翻译做"散列",也有直接音译为"哈希"的,就是把任意长度的输入 (又叫做预映射, pre-image) ,通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,而不可能从散列值来唯一的确定输入值。 以下是java语言的定义: 对象相等则hashCode一定相等; hashCode相等对象未必相等。 这也涉及到如何写自定义的hashCode方法的问题: 必须符合以上条件。注意条件2中的未必。具体可参见java doc; Effective Java中有更详细论述。 补充一点个人简介 hash 就是 类似于数学集合, 每一个键,k可以对应一个或多个值,对象就类似于值,所以"相同的对象"具有相同的键值,也就是hashCode;

2012-09-21 · 1 min · 31 words · -

java Constructor

java Constructor **一、构造器是干什么用的? (what) ** 构造器是用来生成一个类的实例是用来初始化这个实例用的 **二、构造器如何工作? (how) ** Java在构造实例时的顺序是这样的: 分配对象空间,并将对象中成员初始化为0或者空,java不允许用户操纵一个不定值的对象。 执行属性值的显式初始化 执行构造器 4 、将变量关联到堆中的对象上 而执行构造器的步骤有可以分为以下几步: Bind构造器的参数 如果显式的调用了this,那就递归调用this构造器然后跳到步骤5 递归调用显式或者隐式的父类构造器,除了Object以外,因为它没有父类 执行显式的实例变量初始化 (也就是上边的流程中的第二步,调用返回以后执行, 这个步骤相当于在父构造器执行后隐含执行的,看样子像一个特殊处理) 三、构造器不可被orerride (why) 其实你只需要记住一句话: 构造器不是方法,那么用来修饰方法特性的所有修饰符都不能用来修饰构造器 (并不等与构造器 具备这些特性,虽然不能用static修饰构造器,但它却有静态特性) 构造器只能用 public private protected这 三个权限修饰符,且不能有返回语句。 参考: http://doc.linuxpk.com/43476.html

2012-09-21 · 1 min · 35 words · -

java native

java native Java不是完美的,Java的不足除了体现在运行速度上要比传统的C++慢许多之外,Java无法直接访问到操作系统底层 (如系统硬件等),为此Java使用native方法来扩展Java程序的功能。 可以将native方法比作Java程序同C程序的接口,其实现步骤: 1、在Java中声明native()方法,然后编译; 2、用javah产生一个.h文件; 3、写一个.cpp文件实现native导出方法,其中需要包含第二步产生的.h文件 (注意其中又包含了JDK带的jni.h文件) ; 4、将第三步的.cpp文件编译成动态链接库文件; 5、在Java中用System.loadLibrary()方法加载第四步产生的动态链接库文件,这个native()方法就可以在Java中被访问了。 JAVA本地方法适用的情况 1.为了使用底层的主机平台的某个特性,而这个特性不能通过JAVA API访问 2.为了访问一个老的系统或者使用一个已有的库,而这个系统或这个库不是用JAVA编写的 3.为了加快程序的性能,而将一段时间敏感的代码作为本地方法实现。 首先写好JAVA文件 /* Created on 2005-12-19 Author shaoqi */ package com.hode.hodeframework.modelupdate; public class CheckFile { public native void displayHelloWorld(); static { System.loadLibrary(“test”); } public static void main(String[] args) { new CheckFile().displayHelloWorld(); } } 然后根据写好的文件编译成CLASS文件 然后在classes或bin之类的class根目录下执行javah -jni com.hode.hodeframework.modelupdate.CheckFile, 就会在根目录下得到一个com_hode_hodeframework_modelupdate_CheckFile.h的文件 然后根据头文件的内容编写com_hode_hodeframework_modelupdate_CheckFile.c文件 #include “CheckFile.h” #include #include JNIEXPORT void JNICALL Java_com_hode_hodeframework_modelupdate_CheckFile_displayHelloWorld(JNIEnv *env, jobject obj) { printf(“Hello world!n”); return; } 之后编译生成DLL文件如"test.dll",名称与System.loadLibrary(“test”)中的名称一致 vc的编译方法: cl -I%java_home%include -I%java_home%includewin32 -LD com_hode_hodeframework_modelupdate_CheckFile.c -Fetest.dll ...

2012-09-21 · 1 min · 80 words · -

Java assertion

Java assertion ashttp://www.ibm.com/developerworks/cn/java/l-javaassertion/index.html sertion的语法和语义 J2SE 1.4在语言上提供了一个新特性,就是assertion(断言)功能,它是该版本在Java语言方面最大的革新。在软件开发中,assertion是一种经典的调试、测试方式,本文将深入解析assertion功能的使用以及其设计理念,并给出相关的例子 。 assertion(断言)在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制,如C,C++和Eiffel等,但是支持的形式不尽相同,有的是通过语言本身、有的是通过库函数等。另外,从理论上来说,通过assertion方式可以证明程序的正确性,但是这是一项相当复杂的工作,目前还没有太多的实践意义。 在实现中,assertion就是在程序中的一条语句,它对一个boolean表达式进行检查,一个正确程序必须保证这个boolean表达式的值为true;如果该值为false,说明程序已经处于不正确的状态下,系统将给出警告或退出。一般来说,assertion用于保证程序最基本、关键的正确性。assertion检查通常在开发和测试时开启。为了提高性能,在软件发布后,assertion检查通常是关闭的。下面简单介绍一下Java中assertion的实现。 1.1) 语法表示 在语法上,为了支持assertion,Java增加了一个关键字assert。它包括两种表达式,分别如下: assert expression1; assert expression1: expression2; 在两种表达式中,expression1表示一个boolean表达式,expression2表示一个基本类型或者是一个对象(Object) ,基本类型包括boolean,char,double,float,int和long。由于所有类都为Object的子类,因此这个参数可以用于所有对象。 1.2) 语义含义 在运行时,如果关闭了assertion功能,这些语句将不起任何作用。如果打开了assertion功能,那么expression1的值将被计算,如果它的值为false,该语句强抛出一个AssertionError对象。如果assertion语句包括expression2参数,程序将计算出expression2的结果,然后将这个结果作为AssertionError的构造函数的参数,来创建AssertionError对象,并抛出该对象;如果expression1值为true,expression2将不被计算。 一种特殊情况是,如果在计算表达式时,表达式本身抛出Exception,那么assert将停止运行,而抛出这个Exception。 1.3) 一些assertion例子 下面是一些Assert的例子。 assert0 < value; assert0 < value:“value="+value; assertref != null:“ref doesn’t equal null”; assertisBalanced(); 1.4) 编译 由于assert是一个新关键字,使用老版本的JDK是无法编译带有assert的源程序。因此,我们必须使用JDK1.4(或者更新)的Java编译器,在使用Javac命令时,我们必须加上-source 1.4作为参数。-source 1.4表示使用JDK 1.4版本的方式来编译源代码,否则编译就不能通过,因为缺省的Javac编译器使用JDK1.3的语法规则。 一个简单的例子如下: javac -source 1.4 test.java 1.5) 运行 由于带有assert语句的程序运行时,使用了新的ClassLoader和Class类,因此,这种程序必须在JDK1.4(或者更高版本)的JRE下运行,而不能在老版本的JRE下运行。 由于我们可以选择开启assertion功能,或者不开启,另外我们还可以开启一部分类或包的assertion功能,所以运行选项变得有些复杂。通过这些选项,我们可以过滤所有我们不关心的类,只选择我们关心的类或包来观察。下面介绍两类参数: 参数 -esa和 -dsa: 它们含义为开启(关闭)系统类的assertion功能。由于新版本的Java的系统类中,也使了assertion语句,因此如果用户需要观察它们的运行情况,就需要打开系统类的assertion功能 ,我们可使用-esa参数打开,使用 -dsa参数关闭。 -esa和-dsa的全名为-enablesystemassertions和-disenablesystemassertions,全名和缩写名有同样的功能。 参数 -ea和 -ea: 它们含义为开启(关闭)用户类的assertion功能: 通过这个参数,用户可以打开某些类或包的assertion功能,同样用户也可以关闭某些类和包的assertion功能。打开assertion功能参数为-ea;如果不带任何参数,表示打开所有用户类;如果带有包名称或者类名称,表示打开这些类或包;如果包名称后面跟有三个点,代表这个包及其子包;如果只有三个点,代表无名包。关闭assertion功能参数为-da,使用方法与-ea类似。 -ea和-da的全名为-enableassertions和-disenableassertions,全名和缩写名有同样的功能。 下面表格表示了参数及其含义,并有例子说明如何使用。 参数 例子 说明 -ea java -ea 打开所有用户类的assertion -da java -da 关闭所有用户类的assertion -ea:<classname> java -ea:MyClass1 打开MyClass1的assertion -da:<classname> java -da: MyClass1 关闭MyClass1的assertion -ea:<packagename> java -ea:pkg1 打开pkg1包的assertion -da:<packagename> java -da:pkg1 关闭pkg1包的assertion -ea:... java -ea:... 打开缺省包(无名包)的assertion -da:... java -da:... 关闭缺省包(无名包)的assertion -ea:<packagename>... java -ea:pkg1... 打开pkg1包和其子包的assertion -da:<packagename>... java -da:pkg1... 关闭pkg1包和其子包的assertion -esa java -esa 打开系统类的assertion -dsa java -dsa 关闭系统类的assertion 综合使用 java -dsa:MyClass1:pkg1 关闭MyClass1和pkg1包的assertion 其中...代表,此包和其子包的含义。例如我们有两个包为pkg1和pkg1.subpkg。那么pkg1...就代表pkg1和pkg1.subpkg两个包。 另外,Java为了让程序也能够动态开启和关闭某些类和包的assertion功能,Java修该了Class和ClassLoader的实现,增加了几个用于操作assert的API。下面简单说明一下几个API的作用。 ClassLoader类中的几个相关的API: setDefaultAssertionStatus:用于开启/关闭assertion功能 setPackageAssertionStatus:用于开启/关闭某些包的assertion功能 setClassAssertionStatus: 用于开启/关闭某些类的assertion功能 clearAssertionStatus: 用于关闭assertion功能 [回页首][1] assertion的设计问题 首先,我们认为assertion是必要的。因为,如果没有统一的assertion机制,Java程序通常使用if-then-else或者switch-case语句进行assertion检查,而且检查的数据类型也不完全相同。assertion机制让Java程序员用统一的方式处理assertion问题,而不是按自己的方式处理。另外,如果用户使用自己的方式进行检查,那么这些代码在发布以后仍然将起作用,这可能会影响程序的性能。而从语言言层次支持assertion功能,这将把assertion对性能带来的负面影响降到最小。 Java是通过增强一个关键字assert实现支持assertion,而不是使用一个库函数支持,这说明Java认为assertion对于语言本身来说是非常重要的。实际上,在Java的早期的规范中,Java是能够支持assert的,但是由于一些实现的限制,这些特性从规范中除去了。因此,assert的再次引入应该是恢复了Java对assert的支持。C语言就是通过Assert.h函数库实现断言的支持。 Java的assertion的开启也和C语言不太一样,我们都知道在C语言中,assertion的开启是在编译时候决定的。当我们使用debug方式编译程序时候,assertion被开启,而使用release方式编译时候,assertion自动被关闭。而Java的assertion却是在运行的时候进行决定的。其实,这两种方式是各有优缺点。如果采用编译时决定方式,开发人员将处理两种类型的目标码,debug版本和release版本,这加大了文档管理的难度,但是提高了代码的运行效率。Java采用运行时决定的方式,这样所有的assertion信息将置于目标代码中,同一目标代码可以选择不同方式运行,增强目标代码的灵活性,但是它将牺牲因为assertion而引起一部分性能损失。Java专家小组认为,所牺牲的性能相当小,因此java采用了运行时决定方式。 另外,我们注意到AssertionError作为Error的一个子类,而不是RuntimeException。关于这一点,专家组也进行了长期的讨论。Error代表一些异常的错误,通常是不可以恢复的,而RuntimeException强调该错误在运行时才发生的特点。AssertionError通常为非常关键的错误,这些错误往往是不容易恢复的,而且assertion机制也不鼓励程序员对这种错误进行恢复。因此,为了强调assertion的含义,Java专家小组选择了让AssertError为Error的子类。 [回页首][1] assertion与继承 在本节,我们将考虑assertion与继承的关系,研究assert是如何定位的。如果开启一个子类的assertion,那么它的父类的assertion是否执行? 下面的例子将显示如果一个assert语句在父类,而当它的子类调用它时,该assert为false。我们看看在不同的情况下,该assertion是否被处理。 class Base { public void baseMethod() { assert false : “Assertion failed:This is base “;// 总是assertion失败 System.out.println(“Base Method”); } } class Derived extends Base { public void derivedMethod() { assert false: “Assertion failed:This is derive”;// 总是assertion失败 System.out.println( “Derived Method” ); } public static void main( String[] args ) { try { Derived derived = new Derived(); derived.baseMethod( ); derived.derivedMethod(); } catch( AssertionError ae ) { System.out.println(ae); } } } ...

2012-09-21 · 2 min · 368 words · -

Static Nested Class, Inner Class, Anonymous Inner Class

Static Nested Class, Inner Class, Anonymous Inner Class Inner Class (内部类) 定义在类中的类 Nested Class (嵌套类) 是静态 (static) 内部类。 要创建嵌套类的对象,并不需要其外围类的对象。 不能从嵌套类的对象中访问非静态的外围类对象。 Anonymous Inner Class (匿名内部类) 匿名的内部类是没有名字的内部类。 匿名的内部类不能extends (继承) 其它类,但一个内部类可以作为一个接口,由另一个内部类实现。 嵌套类可以作为接口的内部类。正常情况下,你不能在接口内部放置任何代码,但嵌套类可以作为接口的一部分,因为它是static 的。只是将嵌套类置于接口的命名空间内,这并不违反接口的规则。 内部类被继承,由于内部类有一个指向外围类对象的秘密引用,所以在继承内部类的时候,该秘密引用必须被初始化。解决方法是enclosingClassReference.super();语法,看一下代码: class Outer { class Inner { } } class AnoClass extends Outer.Inner { AnoClass (Outer wi) { wi.super(); } } 匿名类 (Anonymous Class) 当一个内部类的类声名只是在创建此类对象时用了一次,而且要产生的新类需继承于一个已有的父类或实现一个接口,才能考虑用匿名类,由于匿名类本身无名,因此它也就不存在构造方法,它需要显示地调用一个无参的父类的构造方法,并且重写父类的方法。 f.addMouseMotionListener(new MouseMotionAdapter(){ //匿名类开始 public void mouseDragged(MouseEvent e){ String s="Mouse dragging: x="+e.getX()+"Y="+e.getY(); tf.setText(s); } } ); //匿名类结束 存在它的原因是: ...

2012-09-21 · 1 min · 89 words · -

forward redirect

forward redirect forward vs redirect forward 是服务器内部重定向,程序收到请求后重新定向到另一个程序,而客户机并不知晓; forward会将 request state、bean、等信息带到下一个jsp页面; 使用getAttribute () 来取得前一个jsp所放的信息 redirect 是服务器收到请求后发送一个状态头给客户,客户将再次请求,就有两次网络通行的来往。 redirect 是送到客户端后再次request,因此上一个jsp的信息不被保留 效率: Forward高, Redirect低, 因为Redirect的流程是这样的, request 1 sent to server, server return back to client, request 2 then sent to server. But Forward 仅在server side处理, 对client side 是透明的. 由于Redirect 有两次传输, 所以效率低. 范围: 由于对request.setAttribute() 来说, 它携带的对象生存范围只在request内, 所以Redirect方式会导致request携带的对象丢失. http://www.iteye.com/topic/3497 http://article2008.iteye.com/blog/173832

2012-09-21 · 1 min · 54 words · -

Java, 堆(Heap), 栈/线程栈(Stack), 方法区(method), 常量池

Java, 堆(Heap), 栈/线程栈(Stack), 方法区(method), 常量池 Java, 堆(Heap), 栈/线程栈(Stack), 方法区(method Area), 常量池(Constant Pool) heap, 堆 堆是线程共享的,所有的对象的实例和数组都存放在堆中,任何线程都可以访问。Java的垃圾自动回收机制就是运用这个区域的。 Stack(栈), thread stacks(线程栈), call stack, Execution stack 栈是线程私有的,每个线程都是自己的栈,每个线程中的每个方法在执行的同时会创建一个栈帧用于保存 PC(程序计数器) 局部变量表、操作数栈、动态链接、方法返回地址等信息。每一个方法从调用到执行完毕的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。其中局部变量表,存放基本类型 (boolean、byte、char、short、int、float) 、对象的引用等等,对象的引用不是对象实例本身,而是指向对象实例的一个指针。 ———————————————— 版权声明: 本文为CSDN博主「万猫学社」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接: https://blog.csdn.net/heihaozi/article/details/102752636 内存指令区,存储数据: 基本数据类型, 指令代码,常量,对象的引用地址(2) Hotspot VM: 栈内存从概念上分 “线程的栈内存” 和 “JVM的栈内存” 两种。 线程的栈内存: 每新建一个线程时,会分配给这个线程一个栈内存初始值,最大的大小可通过 -Xss 来设置。线程占有的栈内存大小,通过不断执行方法,生成局部变量等操作,栈桢不断增加,该线程的栈内存也不断被使用。最终达到 -Xss 的值时,会抛出 StackOverFlowError。其实这里就是线程的栈内存溢出,背后的概念与 OOME 是一样的,只是jvm设计者取的名字不一样而已。3.JVM的栈内存: 当一个jvm进程启动时,会不断消耗 native memory。我们可以通过参数 -Xmx 等来设置堆内存、方法区内存的最大值,当达到阀值时,jvm就会报OOME。但是栈内存大小,则是物理机器的 native memory,其上限就是native memory的上限。不断建线程消耗native memory待尽时,就会报OOME。 作者: chiukong 链接: https://www.zhihu.com/question/28637033/answer/41677862 来源: 知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 保存对象实例,实际上是保存对象实例的属性值,属性的类型和对象本身的类型标记等,并不保存对象的方法 (方法是指令,保存在stack中) 。对象实例在heap中分配好以后,需要在stack中保存一个4字节的heap内存地址,用来定位该对象实例在heap中的位置,便于找到该对象实例。 基本数据类型包括byte、int、char、long、float、double、boolean和short。 函数方法属于指令 引用网上广泛流传的"Java堆和栈的区别"里面对堆和栈的介绍; ...

2012-09-21 · 3 min · 538 words · -

HashMap,Hashtable

HashMap,Hashtable HashMap, Hashtable HashTable的应用非常广泛,HashMap是新框架中用来代替HashTable的类,也就是说建议使用HashMap,不要使用HashTable。可能你觉得HashTable很好用,为什么不用呢?这里简单分析他们的区别。 HashTable的方法是同步的,HashMap未经同步,所以在多线程场合要手动同步HashMap这个区别就像 Vector 和ArrayList一样。 HashTable不允许null值(key和value都不可以), HashMap允许 null 值(key和value都可以)。 hashMap去掉了HashTable 的contains(Object value)方法,但是加上了containsValue ()和containsKey ()方法。 HashTable使用 Enumeration,HashMap使用 Iterator。以上只是表面的不同,它们的实现也有很大的不同。 HashTable中 hash数组默认大小是11,增加的方式是 old*2+1。HashMap 中 hash数组的默认大小是16,而且一定是2的指数。 哈希值的使用不同,HashTable 直接使用对象的hashCode,代码是这样的: int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; //而HashMap重新计算hash值,而且用与代替求模: int hash = hash(k); int i = indexFor(hash, table.length); static int hash(Object x) { int h = x.hashCode(); h += ~(h << 9); h ^= (h >>> 14); h += (h << 4); h ^= (h >>> 10); return h; } static int indexFor(int h, int length) { return h & (length-1); } ``` 以上只是一些比较突出的区别,当然他们的实现上还是有很多不同的,比如 HashMap对null的操作 HashMap可以看作三个视图: key的Set,value的Collection,Entry的Set。 这里HashSet就是其实就是HashMap的一个视图。HashSet内部就是使用Hashmap实现的,和Hashmap不同的是它不需要Key和Value两个值。 往hashset中插入对象其实只不过是内部做了 public boolean add(Object o) { return map.put(o, PRESENT)==null; } HashMap为散列映射,它是基于hash table的一个实现,它可在常量时间内安插元素,或找出一组key-value pair.HashSet为散列集,它把查找时间看的很重要,其中所有元素必须要有hashCode() http://oznyang.iteye.com/blog/30690 http://zhaosoft.iteye.com/blog/243587 http://coolshell.cn/articles/9606.html http://coolshell.cn/articles/9606.html/embed#?secret=NbrQHz1OQo

2012-09-21 · 1 min · 115 words · -