Java踩坑记录

Java构造函数与空指针异常
本文解析Java中构造函数的特性,包括其默认行为、修饰符限制、重载与重写区别,以及void修饰引起的问题。通过具体案例,阐述如何避免因构造函数误解导致的空指针异常。
  • 类的构造函数默认没有返回值(或者认为是本类实例的引用,使用new 类名()会返回一个本类实例的引用);
  • private可以修饰构造函数,但一般不用于修饰类的构造函数,这会导致其他类中不能生成本类的实例(即使在同一个包中,或者使用import关键字);
  • static 不能用于修饰构造函数(构造函数本身用于类实例化时自动调用,设置成static没有意义);
  • void的函数修饰构造函数会引起歧义,“void 类名(){}”,void使得编译器认为"类名()"不再是构造函数(IDEA中,在主函数中实例化后,"函数名()"依然显示灰色表示没有调用),而是一个普通的实例方法,此时再用static修饰该函数,编译器不会报错
  • 构造方法可以被重载,但不能被重写(父子类名字不一样);
public ClassName {
	private ClassName() {
//private 可以用于修饰构造函数,在同时拥有private ClassName()和			
//ClassName()时,编译器会认为前者是构造函数,后者是成员方法;
	}	
	/*
	className() {
		//构造函数;
	}
	void ClassName() {
		//ClassName()不再是构造函数,而是普通的成员方法;
	}
	*/
	static void ClassName() {
		//编译器不会报错,这里static仅用于修饰一个成员方法;
	}

}

在编写网络应用服务器端程序的时,出现错误空指针异常:java.lang.NullPointerException

package zcf.com;
import java.net.*;

public class Server extends Thread {

    String str = "zcf";
    int port = 9999;
    InetAddress intads = null;
    MulticastSocket socket = null;
//添加了void,导致Server()被视为成员方法,本类实例化的时,调用的默认构造方法,没有初始化socket,在run()线程任务中调用socket时,出现空指针异常;
    void Server() {
        try {
            intads = InetAddress.getByName("224.255.1.0");
            socket = new MulticastSocket(port);
            socket.setTimeToLive(1);
            socket.joinGroup(intads);
            if(socket == null) {
                System.out.println("null!");
            }
            }catch(Exception e) {
            e.printStackTrace();
        }
    }

    public void run() {
        while (true) {
            byte data[] = str.getBytes();
            DatagramPacket dPacket = new DatagramPacket(data, data.length, intads, port);
            System.out.println(str);
            try {
                socket.send(dPacket);
                sleep(3000);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) {
        Server server = new Server();
        server.start();
    }
}

执行结果:

//报出异常;
java.lang.NullPointerException
	at zcf.com.Server.run(Server.java:31)

去掉void修饰符:

//结果正常,间隔数秒发送一个信息;
zcf
zcf

在使用 Java 进行 PDF 模板填充表单时,开发者常常会遇到一些技术难点和常见问题。以下是总结的几个常见问题及其解决方案: ### 1. **PDF 模板字段名称不匹配** 当使用 iText 或其他库进行 PDF 表单填充时,如果模板中的字段名称与代码中指定的字段名不一致,会导致数据无法正确填充。例如,字段名拼写错误、大小写不一致或字段名不存在等问题[^2]。 **解决方案**: - 在代码中使用 `AcroFields` 获取字段值时,确保字段名称与模板中的名称完全一致。 - 使用工具(如 Adobe Acrobat)查看 PDF 表单字段的名称,确保字段可编辑且名称正确。 - 可以通过以下代码检查字段是否存在: ```java PdfReader reader = new PdfReader("template.pdf"); AcroFields fields = reader.getAcroFields(); Set<String> fieldNames = fields.getFields().keySet(); System.out.println("Available fields: " + fieldNames); ``` ### 2. **PDF 模板字段不可编辑** 某些 PDF 模板可能被设置为只读,或者字段被锁定,导致程序无法修改其内容。这种情况通常发生在从扫描文档或受保护的 PDF 创建的模板中[^2]。 **解决方案**: - 使用 Adobe Acrobat 打开 PDF,进入“表单编辑模式”,确保所有字段为可编辑状态。 - 如果模板受密码保护,需提供正确的密码以解锁文档。 - 在代码中使用 `PdfStamper` 时,可以通过设置 `PdfWriter.ALLOW_FILL_IN` 权限来确保字段可编辑: ```java PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("output.pdf")); stamper.setFormFlattening(false); // false 表示保留表单字段可编辑 ``` ### 3. **中文显示异常或乱码** 在填充 PDF 表单时,如果涉及中文字符,可能会出现乱码或显示为方框。这是因为 PDF 默认字体不支持中文字符集。 **解决方案**: - 使用 `BaseFont` 加载中文字体文件(如 `simsun.ttc` 或 `SimHei.ttf`),并将其应用到字段中: ```java BaseFont bf = BaseFont.createFont("simsun.ttc,0", BaseFont.IDENTITY_H, BaseFont.EMBEDDED); AcroFields form = stamper.getAcroFields(); form.addSubstitutionFont(bf); form.setField("name", "张三"); ``` - 确保字体文件路径正确,并且字体文件具有合法的使用权限。 ### 4. **表单字段布局错乱或内容截断** 有时,填充的数据长度超出字段的显示区域,导致内容被截断或布局错乱。 **解决方案**: - 在设计 PDF 模板时,预留足够的空间以容纳较长的内容。 - 对于多行文本字段,启用“多行”属性,允许内容自动换行。 - 在代码中设置字段的文本对齐方式和字体大小: ```java form.setFieldProperty("description", "textsize", 10f, null); form.setFieldProperty("description", "textalignment", Element.ALIGN_JUSTIFIED, null); ``` ### 5. **生成的 PDF 文件无法打开或损坏** 有时生成的 PDF 文件在某些 PDF 阅读器中无法正常打开,提示文件损坏。 **解决方案**: - 确保在操作完成后正确关闭所有流和资源: ```java stamper.close(); reader.close(); ``` - 检查文件是否被多个线程或进程同时写入。 - 使用标准的 PDF 阅读器(如 Adobe Acrobat Reader)进行测试,排除阅读器兼容性问题。 ### 6. **字段填充后无法保存或扁平化** 在某些情况下,生成的 PDF 表单字段在填充后仍然可编辑,或者在扁平化后字段内容丢失。 **解决方案**: - 使用 `setFormFlattening(true)` 方法将表单字段扁平化,使其不可编辑: ```java stamper.setFormFlattening(true); ``` - 扁平化操作应在所有字段填充完成后执行,以确保内容正确保留。 ### 7. **处理多页表单时字段定位错误** 在处理多页 PDF 表单时,字段可能出现在不同的页面上,导致填充时定位错误。 **解决方案**: - 使用 `AcroFields` 提供的 `setField` 方法时,无需关心字段所在的页面,iText 会自动处理多页字段。 - 如果需要在特定页面上添加内容,可以结合 `PdfContentByte` 和页面编号进行操作。 ### 8. **依赖版本冲突或功能限制** 使用 iText 的不同版本可能导致 API 不兼容,或者某些功能(如加密、表单扁平化)在旧版本中不可用。 **解决方案**: - 确保项目中使用的 iText 版本为 5.x(如 5.5.13.3)或 7.x(如 `itext7`),并根据版本选择合适的 API。 - 更新 `pom.xml` 中的依赖配置,确保版本一致且功能完整: ```xml <dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> <version>5.5.13.3</version> </dependency> ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值