深入剖析Java编程中的序列化_java

 Java提供一种机制叫做序列化,通过有序的格式或者字节序列持久化java对象,其中包含对象的数据,还有对象的类型,和保存在对象中的数据类型。

所以,如果我们已经序列化了一个对象,那么它可以被读取并通过对象的类型和其他信息进行反序列化,并最终获取对象的原型。

ObjectInputStream 和 ObjectOutputStream对象是高级别的流对象,包含序列化和反序列化的方法。

ObjectOutputStream 拥有很多序列化对象的方法,最常用的是:
 

private void writeObject(ObjectOutputStream os) throws IOException
 {

 }

类似的 ObjectInputStream 提供如下方法:
 

 private void readObject(ObjectInputStream is) throws IOException, ClassNotFoundException
 {

 }

那么哪里会需要序列化呢?序列化通常在需要通过网络传输数据,或者保存对象到文件的场合使用。这里说的数据是对象而不是文本。

现在的问题是,我们的网络架构和硬盘都只能识别二进制和字节,而不能识别Java对象。

序列化就是把Java对象中的value/states翻译为字节,以便通过网络传输或者保存。另外,反序列化就是通过读取字节码,并把它翻译回java对象。

serialVersionUID概念

serialVersionUID 是用于保证同一个对象(在序列化中会被用到)可以在Deserialization过程中被载入。serialVersionUID 是用于对象的版本控制。你可以参考serialVersionUID in java serialization获取更多信息。

对于序列化:

步骤如下:

让我们看一个列子:

在 src->org.arpit.javapostsforlearning 创建Employee.java

1.Employee.java 
 

package org.arpit.javapostsforlearning;
import java.io.Serializable;
public class Employee implements Serializable{

 int employeeId;
 String employeeName;
 String department;

 public int getEmployeeId() {
  return employeeId;
 }
 public void setEmployeeId(int employeeId) {
  this.employeeId = employeeId;
 }
 public String getEmployeeName() {
  return employeeName;
 }
 public void setEmployeeName(String employeeName) {
  this.employeeName = employeeName;
 }
 public String getDepartment() {
  return department;
 }
 public void setDepartment(String department) {
  this.department = department;
 }
}

就如你所见的,如果你需要序列化任何类,那么你 必须实现 Serializable 接口 ,这个接口是标记接口(marker interface)。

Java中的标记接口(marker interface)就是一个没有任何字段或者方法的接口,简单的来说,java中把空接口叫做标记接口(marker interface)

2.SerializeMain.java
 

package org.arpit.javapostsforlearning;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
 public class SerializeMain {

 /**
 * @author Arpit Mandliya
 */
 public static void main(String[] args) {

 Employee emp = new Employee();
 emp.setEmployeeId(101);
 emp.setEmployeeName("Arpit");
 emp.setDepartment("CS");
 try
 {
 FileOutputStream fileOut = new FileOutputStream("employee.ser");
 ObjectOutputStream outStream = new ObjectOutputStream(fileOut);
 outStream.writeObject(emp);
 outStream.close();
 fileOut.close();
 }catch(IOException i)
 {
 i.printStackTrace();
 }
 }
}

对于反序列化:
步骤是

在包src->org.arpit.javapostsforlearning中,创建 DeserializeMain.java
3.DeserializeMain.java
 

package org.arpit.javapostsforlearning;
import java.io.IOException;
import java.io.ObjectInputStream;

public class DeserializeMain {
 /**
 * @author Arpit Mandliya
 */
 public static void main(String[] args) {

 Employee emp = null;
  try
  {
   FileInputStream fileIn =new FileInputStream("employee.ser");
   ObjectInputStream in = new ObjectInputStream(fileIn);
   emp = (Employee) in.readObject();
   in.close();
   fileIn.close();
  }catch(IOException i)
  {
   i.printStackTrace();
   return;
  }catch(ClassNotFoundException c)
  {
   System.out.println("Employee class not found");
   c.printStackTrace();
   return;
  }
  System.out.println("Deserialized Employee...");
  System.out.println("Emp id: " + emp.getEmployeeId());
  System.out.println("Name: " + emp.getEmployeeName());
  System.out.println("Department: " + emp.getDepartment());
 }
}

4.运行:
首先运行SerializeMain.java,然后运行 DeserializeMain.java,你会得到如下的结果:
 

Deserialized Employee...
Emp id: 101
Name: Arpit
Department: CS

就这样,我们序列化了一个employee对象,并对它进行反序列化。这看起来和简单,但是如果其中包含对象引用,继承,那么情况就会变得复杂。接下来让我们一个接一个的看一下例子,看看如何在各种场合中实现序列化。

案例1 - 如果对象引用了其他对象,那该如何

我们已经看过最简单的序列化例子,现在看看,如何处理对象中引用了其他对象的场合。我们该如何序列化?引用对象也会被序列化吗?对的,你不需要显式的序列化引用对象。当你序列化任何对象,如果它包含引用对象,那么Java序列化会自动序列化该对象的整个对象图。例如,Employee现在引用了一个address对象,并且Address也引用了其他对象(例如,Home),那么当你序列化Employee对象的时候,所有其他引用对象,例如address和home将会被自动地被序列化。让我们来创建Address类,并它Address的对象作为引用,添加到employee类中。

Employee.java: 
 

package org.arpit.javapostsforlearning;
import java.io.Serializable;

public class Employee implements Serializable{

 int employeeId;
 String employeeName;
 String department;
 Address address;

 public int getEmployeeId() {
 return employeeId;
 }
 public void setEmployeeId(int employeeId) {
 this.employeeId = employeeId;
 }
 public String getEmployeeName() {
 return employeeName;
 }
 public void setEmployeeName(String employeeName) {
 this.employeeName = employeeName;
 }
 public String getDepartment() {
 return department;
 }
 public void setDepartment(String department) {
 this.department = department;
 }
 public Address getAddress() {
 return address;
 }
 public void setAddress(Address address) {
 this.address = address;
 }
}

在 org.arpit.javapostsforlearning 包中,创建Address.java
Address.java: 
 

package org.arpit.javapostsforlearning;
public class Address {

 int homeNo;
 String street;
 String city;
 public Address(int homeNo, String street, String city) {
 super();
 this.homeNo = homeNo;
 this.street = street;
 this.city = city;
 }
 public int getHomeNo() {
 return homeNo;
 }
 public void setHomeNo(int homeNo) {
 this.homeNo = homeNo;
 }
 public String getStreet() {
 return street;
 }
 public void setStreet(String street) {
 this.street = street;
 }
 public String getCity() {
 return city;
 }
 public void setCity(String city) {
 this.city = city;
 }
}

在包 org.arpit.javapostsforlearning中,创建SerializeDeserializeMain.java
SerializeDeserializeMain.java:
 

package org.arpit.javapostsforlearning;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class SerializeDeserializeMain {
 /**
 * @author Arpit Mandliya
 */
 public static void main(String[] args) {

 Employee emp = new Employee();
 emp.setEmployeeId(101);
 emp.setEmployeeName("Arpit");
 emp.setDepartment("CS");
 Address address=new Address(88,"MG road","Pune");
 emp.setAddress(address);
 //Serialize
 try
 {
 FileOutputStream fileOut = new FileOutputStream("employee.ser");
 ObjectOutputStream outStream = new ObjectOutputStream(fileOut);
 outStream.writeObject(emp);
 outStream.close();
 fileOut.close();
 }catch(IOException i)
 {
 i.printStackTrace();
 }

 //Deserialize
 emp = null;
 try
 {
 FileInputStream fileIn =new FileInputStream("employee.ser");
 ObjectInputStream in = new ObjectInputStream(fileIn);
 emp = (Employee) in.readObject();
 in.close();
 fileIn.close();
 }catch(IOException i)
 {
 i.printStackTrace();
 return;
 }catch(ClassNotFoundException c)
 {
 System.out.println("Employee class not found");
 c.printStackTrace();
 return;
 }
 System.out.println("Deserialized Employee...");
 System.out.println("Emp id: " + emp.getEmployeeId());
 System.out.println("Name: " + emp.getEmployeeName());
 System.out.println("Department: " + emp.getDepartment());
 address=emp.getAddress();
 System.out.println("City :"+address.getCity());
 }
}

运行它:
当你运行SerializeDeserializeMain.java。你会得到这样的结果:
 

java.io.NotSerializableException: org.arpit.javapostsforlearning.Address
 at java.io.ObjectOutputStream.writeObject0(Unknown Source)
 at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
 at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
 at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
 at java.io.ObjectOutputStream.writeObject0(Unknown Source)
 at java.io.ObjectOutputStream.writeObject(Unknown Source)

我们将解释哪里出错了。我忘记了说,Address 类也必须是serializable。那么Address类必须继承serialzable接口。

Address.java:
 

import java.io.Serializable;

public class Address implements Serializable{

 int homeNo;
 String street;
 String city;
 public Address(int homeNo, String street, String city) {
 super();
 this.homeNo = homeNo;
 this.street = street;
 this.city = city;
 }
 public int getHomeNo() {
 return homeNo;
 }
 public void setHomeNo(int homeNo) {
 this.homeNo = homeNo;
 }
 public String getStreet() {
 return street;
 }
 public void setStreet(String street) {
 this.street = street;
 }
 public String getCity() {
 return city;
 }
 public void setCity(String city) {
 this.city = city;
 }
}

再次运行:
当你再次运行SerializeDeserializeMain.java。你可以得到如下的结果
 

Deserialized Employee...
Emp id: 101
Name: Arpit
Department: CS
City :Pune

案例2:如果我们不能访问引用对象的源代码(例如,你不能访问上面的Address类的源码)

如果我们不能访问到address类,那么我们该如何在Address类中实现serializable 接口?是否有另外的途径来实现呢?对的,你可以创建另外一个类,并继承Address,然后让它继承serializable 接口,但是对于下面的情况,这个方案会失败:

    如果引用类被定义为final
    如果引用类引用了另外一个非可序列化的对象

那么,我们该如何序列化Employee对象?解决的办法是,标记transient。如果你不需要序列化任何字段,只需把它标记为transient。
 
transient Address address
在Employee类中,标记了address为transient之后,运行程序。你会得到nullPointerException,因为在反序列化过程中,Address引用将会是null。

案例3 - 如果我仍然需要保存引用对象的状态呢?(例如address对象)

如果你在反序列化过程中,标记了address为transient,它将会返回null结果。但是如果你仍然需要保存它的状态,你就需要序列化address对象。 Java序列化提供一个机制,如果你有特定签名的private方法,那么它们就会在序列化和反序列化过程中被调用,所以我们将重写Employee类的writeObject和readObject方法,然后它们就会在Employee对象序列化/反序列化过程中被调用。

Employee.java:

package org.arpit.javapostsforlearning;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class Employee implements Serializable{

 int employeeId;
 String employeeName;
 String department;
 transient Address address;

 public int getEmployeeId() {
 return employeeId;
 }
 public void setEmployeeId(int employeeId) {
 this.employeeId = employeeId;
 }
 public String getEmployeeName() {
 return employeeName;
 }
 public void setEmployeeName(String employeeName) {
 this.employeeName = employeeName;
 }
 public String getDepartment() {
 return department;
 }
 public void setDepartment(String department) {
 this.department = department;
 }
 public Address getAddress() {
 return address;
 }
 public void setAddress(Address address) {
 this.address = address;
 }

 private void writeObject(ObjectOutputStream os) throws IOException, ClassNotFoundException
 {
 try {
 os.defaultWriteObject();
 os.writeInt(address.getHomeNo());
 os.writeObject(address.getStreet());
 os.writeObject(address.getCity());
 }
 catch (Exception e)
 { e.printStackTrace(); }
 }

 private void readObject(ObjectInputStream is) throws IOException, ClassNotFoundException
 {
 try {
 is.defaultReadObject();
 int homeNo=is.readInt();
 String street=(String) is.readObject();
 String city=(String) is.readObject();
 address=new Address(homeNo,street,city);

 } catch (Exception e) { e.printStackTrace(); }
 }
}

另外有一点需要牢记的,ObjectInputStream读取数据的顺序和ObjectOutputStream写入数据的顺序是一致的.

在包org.arpit.javapostsforlearning 中创建Address.java
Address.java: 
 

package org.arpit.javapostsforlearning;
import java.io.Serializable;

public class Address {

 int homeNo;
 String street;
 String city;

 public Address(int homeNo, String street, String city) {
 super();
 this.homeNo = homeNo;
 this.street = street;
 this.city = city;
 }
 public int getHomeNo() {
 return homeNo;
 }
 public void setHomeNo(int homeNo) {
 this.homeNo = homeNo;
 }
 public String getStreet() {
 return street;
 }
 public void setStreet(String street) {
 this.street = street;
 }
 public String getCity() {
 return city;
 }
 public void setCity(String city) {
 this.city = city;
 }
}

在包org.arpit.javapostsforlearning中创建SerializeDeserializeMain.java
SerializeDeserializeMain.java:
 

package org.arpit.javapostsforlearning;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class SerializeDeserializeMain {
 /**
 * @author Arpit Mandliya
 */
 public static void main(String[] args) {

 Employee emp = new Employee();
 emp.setEmployeeId(101);
 emp.setEmployeeName("Arpit");
 emp.setDepartment("CS");
 Address address=new Address(88,"MG road","Pune");
 emp.setAddress(address);
 //Serialize
 try
 {
 FileOutputStream fileOut = new FileOutputStream("employee.ser");
 ObjectOutputStream outStream = new ObjectOutputStream(fileOut);
 outStream.writeObject(emp);
 outStream.close();
 fileOut.close();
 }catch(IOException i)
 {
 i.printStackTrace();
 }

 //Deserialize
 emp = null;
 try
 {
 FileInputStream fileIn =new FileInputStream("employee.ser");
 ObjectInputStream in = new ObjectInputStream(fileIn);
 emp = (Employee) in.readObject();
 in.close();
 fileIn.close();
 }catch(IOException i)
 {
 i.printStackTrace();
 return;
 }catch(ClassNotFoundException c)
 {
 System.out.println("Employee class not found");
 c.printStackTrace();
 return;
 }
 System.out.println("Deserialized Employee...");
 System.out.println("Emp id: " + emp.getEmployeeId());
 System.out.println("Name: " + emp.getEmployeeName());
 System.out.println("Department: " + emp.getDepartment());
 address=emp.getAddress();
 System.out.println("City :"+address.getCity());
 }
}

运行 :
当你运行SerializeDeserializeMain.java.你会得到如下的结果: 
 

Deserialized Employee...
Emp id: 101
Name: Arpit
Department: CS
City :Pune

现在我们就得到了address对象的状态,就如它被序列化前的一样。

序列化中的继承:

现在我们看看继承是如何影响序列化的。不管父类是不是可序列化,这将引出很多个例子。如果父类是非可序列化的,我们将如何处理,并且它是如何工作的。让我们看看例子。

我们将创建一个Person.java,作为 Employee的父类。

案例4: 如果父类是可序列化的

如果父类可序列化,那么所有的继承类将是可序列化的。

案例5: 如果父类为非可序列化呢?

如果父类为非可序列化的 ,那么我们的处理办法会很不一样。

    如果父类为非可序列化的,那么它必然不会有参数构造函数。

Person.java 
 

package org.arpit.javapostsforlearning;
public class Person {

 String name="default";
 String nationality;

 public Person()
 {
 System.out.println("Person:Constructor");
 }

 public Person(String name, String nationality) {
 super();
 this.name = name;
 this.nationality = nationality;
 }

 public String getName() {
 return name;
 }

 public void setName(String name) {
 this.name = name;
 }

 public String getNationality() {
 return nationality;
 }

 public void setNationality(String nationality) {
 this.nationality = nationality;
 }

}

在包org.arpit.javapostsforlearning 中创建Employee.java
Employee.java:

 

package org.arpit.javapostsforlearning;
import java.io.Serializable;

public class Employee extends Person implements Serializable{

 int employeeId;
 String department;

 public Employee(int employeeId,String name,String department,String nationality)
 {
 super(name,nationality);
 this.employeeId=employeeId;
 this.department=department;
 System.out.println("Employee:Constructor");
 }

 public int getEmployeeId() {
 return employeeId;
 }
 public void setEmployeeId(int employeeId) {
 this.employeeId = employeeId;
 }

 public String getDepartment() {
 return department;
 }
 public void setDepartment(String department) {
 this.department = department;
 }
}

在org.arpit.javapostsforlearning包中创建SerializeDeserializeMain.java

SerializeDeserializeMain.java:


package org.arpit.javapostsforlearning;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class SerializeDeserializeMain {

 /**
 * @author Arpit Mandliya
 */
 public static void main(String[] args) {

 //Serialize
 Employee emp = new Employee(101,"Arpit","CS","Indian");
 System.out.println("Before serializing");
 System.out.println("Emp id: " + emp.getEmployeeId());
 System.out.println("Name: " + emp.getName());
 System.out.println("Department: " + emp.getDepartment());
 System.out.println("Nationality: " + emp.getNationality());
 System.out.println("************");
 System.out.println("Serializing");
 try
 {
 FileOutputStream fileOut = new FileOutputStream("employee.ser");
 ObjectOutputStream outStream = new ObjectOutputStream(fileOut);
 outStream.writeObject(emp);
 outStream.close();
 fileOut.close();
 }catch(IOException i)
 {
 i.printStackTrace();
 }

 //Deserialize
 System.out.println("************");
 System.out.println("Deserializing");
 emp = null;
 try
 {
 FileInputStream fileIn =new FileInputStream("employee.ser");
 ObjectInputStream in = new ObjectInputStream(fileIn);
 emp = (Employee) in.readObject();
 in.close();
 fileIn.close();
 }catch(IOException i)
 {
 i.printStackTrace();
 return;
 }catch(ClassNotFoundException c)
 {
 System.out.println("Employee class not found");
 c.printStackTrace();
 return;
 }
 System.out.println("After serializing");
 System.out.println("Emp id: " + emp.getEmployeeId());
 System.out.println("Name: " + emp.getName());
 System.out.println("Department: " + emp.getDepartment());
 System.out.println("Nationality: " + emp.getNationality());
 }
}

运行:

当你运行SerializeDeserializeMain.java后,你会得到如下的输出,如果父类是非可序列化的,那么在反序列化过程中,所有继承于父类的实例变量值,将会通过调用非序列化构造函数来初始化。 这里 name继承于person,所以在反序列化过程中,name将会被初始化为默认值。


案例6 - 如果父类是可序列化,但你不需要继承类为可序列化

如果你不希望继承类为可序列化,那么你需要实现 writeObject() 和readObject() 方法,并且需要抛出NotSerializableException 异常。

案例7 - 可否序列化静态变量?

不能。因为静态变量是类级别的,不是对象级别的,当你序列化一个对象的时候,是不能序列化静态变量。

总结:

  •     序列化是java对象的values/states转化为字节并在网络中传输或者保存它的过程。另外反序列化是把字节码翻译为对应的对象的过程。
  •     序列化的好处是,JVM的独立性,也就是说,一个对象可以在一个平台中被序列化,然后在另外一个不同的平台反序列化。
  •     如果你需要序列化任何对象,你必须实现标记接口Serializable。
  •     Java中的标记接口(Marker interface)就是没有字段或者方法的接口,或者更简单的说,空接口
  •     serialVersionUID 是用于保证同一个对象(在序列化中会被用到)可以在Deserialization过程中被载入。serialVersionUID 是用于对象的版本控制。
  •     当你需要序列化任何包含引用对象的对象,那么Java会自动序列化该对象的整个对象图。
  •     如果你不希望序列化某个字段,你可以标记它为trasient
  •     如果父类为可序列化,那么它的继承类也将是可序列化的。
  •     如果父类为非可序列化,那么在反序列化过程中,所有继承于父类的实例变量值将会通过调用非可序列化的构造器来初始化。
  •     如果你需希望子类为可序列化的,那么你需要实现writeObject() 和 readObject() 方法,并在这两个方法中抛出NotSerializableException异常
  •     你不能序列化静态变量。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索java
序列化
深入剖析android系统、深入剖析tomcat、深入剖析nginx、深入剖析、深入剖析nginx pdf,以便于您获取更多的相关知识。

时间: 2024-11-02 05:14:50

深入剖析Java编程中的序列化_java的相关文章

在Java编程中定义方法_java

方法包含一个方法头和一个方法体.下面是一个方法的所有部分: 修饰符:修饰符,这是可选的,告诉编译器如何调用该方法.定义了该方法的访问类型. 返回值类型 :方法可能会返回值.returnValueType是方法返回值的数据类型.有些方法执行所需的操作,但没有返回值.在这种情况下,returnValueType是关键字void. 方法名:是方法的实际名称.方法名和参数表共同构成方法签名. 参数类型:参数像是一个占位符.当方法被调用时,传递值给参数.这个值被称为实参或变量.参数列表是指方法的参数类型.

在Java编程中使用正则表达式_java

在程序设计过程中,经常需要对输入的数据格式进行检查,这时就会用到正则表达式,匹配正则表达式则数据格式正确,否则格式错误.为了检查输入的数据是否满足某种格式,可以使用String类的matches()方法进行判断,语法格式如下: boolean matches(String regex) regex:指定的正则表达式. 返回值:返回boolean类型. 该方法用于告知当前字符串是否匹配参数regex指定的正则表达式,返回值是boolean类型,如果当前字符串与正则表达式匹配,则该方法返回true,

举例讲解设计模式中的访问者模式在Java编程中的运用_java

访问者(Visitor)模式:封装一些作用于某种数据结构中的各元素的操作,它可以在不改变这个数据结构的前提下定义作用于这些元素的新的操作.访问者模式的结构图如下: 通过上图可以看到他有如下角色:抽象访问者(Visitor)角色:定义接口,声明一个或多个访问操作. 具体访问者(ConcreteVisitor)角色:实现抽象访问者所声明的接口,也就是抽象访问者所声明的各个访问操作. 抽象元素(Visitable)角色:声明一个接受操作,接受一个访问者对象作为一个参数. 具体元素结点(Concrete

深入解析Java编程中的抽象类_java

Java程序用抽象类(abstract class)来实现自然界的抽象概念.抽象类的作用在于将许多有关的类组织在一起,提供一个公共的类,即抽象类,而那些被它组织在一起的具体的类将作为它的子类由它派生出来.抽象类刻画了公有行为的特征,并通过继承机制传送给它的派生类.在抽象类中定义的方法称为抽象方法,这些方法只有方法头的声明,而用一个分号来代替方法体的定义,即只定义成员方法的接口形式,而没有具体操作.只有派生类对抽象成员方法的重定义才真正实现与该派生类相关的操作. 在各子类继承了父类的抽象方法之后,

Java编程中10个最佳的异常处理技巧_java

在实践中,异常处理不单单是知道语法这么简单.编写健壮的代码是更像是一门艺术,在本文中,将讨论Java异常处理最佳实践.这些Java最佳实践遵循标准的JDK库,和几个处理错误和异常的开源代码.这还是一个提供给java程序员编写健壮代码的便利手册.Java 编程中异常处理的最佳实践 这里是我收集的10个Java编程中进行异常处理的10最佳实践.在Java编程中对于检查异常有褒有贬,强制处理异常是一门语言的功能.在本文中,我们将尽量减少使用检查型异常,同时学会在Java编程中使用检查型VS非检查型异常

深入理解Java编程中异常处理的优劣_java

Java编程中的异常处理是一个很常见的话题了,几乎任何一门介绍性的Java课程都会提到异常处理.不过,我认为很多人其实没有真正掌握正确处理异常情况的方法和策略,最多也就不过了解个大概,知道概念.我想对三种不同程度和质量的Java异常处理进行了讨论,所阐述的处理异常的方式按手法的高下分为:好,不好和恶劣三种.同时提供了一些解决这些问题的技巧.首先解释一些java异常处理中必须搞清楚的定义和机制.Java语言规范将自Error类或RuntimeException类衍生出来的任何违例都称作"不可检查&

java代码-关于CSDN英雄会挑战赛 java编程中的一些问题

问题描述 关于CSDN英雄会挑战赛 java编程中的一些问题 各位大神,我在挑战英雄会的题目的时候,在线下运行的没有问题,可是一提交就会提示,"挑战失败:你的程序正常编译,不过运行时发生错误,通常是代码有问题,如除数为零数组上下界溢出等" 我觉得可能是java输入数据时的问题,因为题目要求:输入多行数据,输出多行我是这样写的: Scanner scanner = new Scanner(System.in); ArrayList list = new ArrayList(); do {

仔细触摸Java编程中的“文档”和“包”

编程 什么是包 Java中的包(Package)其实指的就是目录,它是为了更好地管理Java类(Class)和接口(Interface).Java语言的包可以被另一个Java开发包所使用.如果我们要引用某个包中的类,用import关键字来标明即可.比如: import java.util. date=new Date  提示:import java.util.表示java.util中的所有公有类和接口被引入到当前包.这里的匹配符可以调入多个类名. 常用的Java标准包 JDK为我

跨越边界: 活动记录和Java编程中特定于域的语言

DSL 是专门解决特定于域问题的语言.通过更接近问题的操作,DSL 可以提供在通用语言中可能找不 到的好处.Java 世界中充满了 DSL.属性文件.Spring 上下文.标注的某种用法以及 Ant 任务,都是 DSL 的示例. 在开始研究其他像 Ruby 这样的语言的时候,我开始理解到 Java 语言目前对于 DSL 还没有良好的把 握.在这篇文章中,将看到 Ruby 使用的四种集成干净的 DSL 的技巧.然后,将看到在 Java 语言中可 能存在的选项是什么. 隐藏语言的世界 虽然您可能不知