<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns:MadCap="http://www.madcapsoftware.com/Schemas/MadCap.xsd" MadCap:lastBlockDepth="2" MadCap:lastHeight="120" MadCap:lastWidth="624" MadCap:disableMasterStylesheet="true" MadCap:tocPath="" MadCap:InPreviewMode="false" MadCap:RuntimeFileType="Topic" MadCap:TargetType="WebHelp" MadCap:PathToHelpSystem="../../../../" MadCap:HelpSystemFileName="index.xml" MadCap:SearchType="Stem"> <head><title>Final Fields Specifics </title> <script type="text/javascript">/* <![CDATA[ */ window.onload = function(){ var pathToFlash = $('html').attr('MadCap:PathToHelpSystem') + 'Content/Resources/Code/ZeroClipboard.swf'; ZeroClipboard.setMoviePath(pathToFlash); function bindToClipBord(element,content){ var clip = new ZeroClipboard.Client(); clip.setText(content); clip.glue(element); }; if(location.protocol==='file:'){ $('.copylink-marker').remove(); } else{ $('.copylink-marker').each(function(){ var text = $(this).parent().parent().children('.prettyprint').html(); $(this).hover(function(){ bindToClipBord(this,text); }, function(){}); }); } prettyPrint(); }; /* ]]> */</script> <link href="../../../SkinSupport/MadCap.css" rel="stylesheet" /> <link href="../../../Resources/Stylesheets/OnlineStyle.css" rel="stylesheet" /> <script src="../../../Resources/Code/prettify.js"> </script> <script src="../../../Resources/Code/lang-vb.js"> </script> <script src="../../../Resources/Code/jquery.min.js"> </script> <script src="../../../Resources/Code/ZeroClipboard.js"> </script> <script src="../../../SkinSupport/MadCapAll.js" type="text/javascript"> </script> </head> <body> <p class="MCWebHelpFramesetLink" style="display: none;"><a href="../../../../index_CSH.html#advanced_topics/type_handling/final_fields/final_fields_specifics.htm" style="">Open topic with navigation</a> </p> <p> <script type="text/javascript">/*<![CDATA[*/document.write('<a href="' + location.href +'">'); document.write("Direct Link"); document.write('</a>');/*]]>*/</script> </p> <p> </p> <h1>Final Fields Specifics</h1> <p>Db4o uses reflection to store and retrieve objects from the database file. In the case of final fields db4o needs a successful call to java.lang.Field#setAccessible to allow write access to those fields. Unfortunately different Java versions produce different results in this case. To be more specific:</p> <ul> <li value="1">In (Sun) JDK 1.-1.2 java.lang.Field#setAccessible call will be successful for the fields with the final modifier. </li> <li value="2">This behavior was changed for JDK1.3-1.4 as the API documentation for java.lang.Field#set() made a quite clear distinction between 'Java language access control' (visibility modifiers, affected by setAccessible()) and final fields (not affected by setAccessible()). For more information refer to <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4250960">java bug 4250960</a>.</li> <li value="3">The behavior of java.lang.Field#setAccessible method was changed again for JDK5 and JDK6. The access to final fields was made manageable by setAccessible() call to accommodate for the extended semantics of the final modifier for the revised Java memory model. The API documentation of java.lang.Field#set() was changed accordingly. See <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5044412">java bug 5044412</a>.</li> </ul> <p>You can use the following example code to check final fields behavior with different java versions:</p> <pre class="prettyprint" xml:space="preserve">TestFinal.java /**//* Copyright (C) 2007 Versant Inc. http://www.db4o.com */ package com.db4odoc.finalfields; import java.io.File; import com.db4o.Db4o; import com.db4o.ObjectContainer; import com.db4o.ObjectSet; public class TestFinal { private static final String DB4O_FILE_NAME = "reference.db4o"; // non-final fields public int _i; public String _s; // final fields storing the same values as above public final int _final_i; public final String _final_s; public static void main(String[] args) { new File(DB4O_FILE_NAME).delete(); ObjectContainer container = Db4o.openFile(DB4O_FILE_NAME); try { TestFinal test = new TestFinal(1,"test"); container.store(test); System.out.println("Added: " + test); } finally { // Close does implicit commit and refreshes the reference cache container.close(); } container = Db4o.openFile(DB4O_FILE_NAME); try { ObjectSet result = container.queryByExample(null); listResult(result); } finally { container.close(); } } // end main public TestFinal(int i, String s) { // initialize final and non-final fields with the same values _i = i; _s = s; _final_i = i; _final_s = s; } // end TestFinal public String toString() { return "Int - " + _i + "; String - " + _s + "; FINAL Int - " + _final_i + "; FINAL String - " + _final_s; } // end toString private static void listResult(ObjectSet result) { while(result.hasNext()) { System.out.println(result.next()); } } // end listResult }</pre> <p>If you are using Eclipse it is easy to switch between java versions - you can switch to the versions lower than the one installed on your computer without having to install them all. For example if you are using JDK6 you can easily test your project on JDK1.1 - 1.4 and JDK5. Just go to the project properties, select "Java Build Path" on the left panel and "Libraries" tab on the right panel. Remove the system library currently used. Select "Add library->JRE System Library"; on the next screen check the "Execution Environment" radio button and select the desired environment from the list.</p>Don't forget to use the appropriate db4o version for the selected java environment version. See db4o on Java Platformsfor more information. <p MadCap:conditions="Primary.Online">Download example code:</p><script type="text/javascript" src="../../../SkinSupport/MadCapBodyEnd.js"></script></body> </html>