JDK 7で追加されるクラス・メソッドを一覧してみようと思いました。標準APIのソースコードはJDKと一緒にインストールされるので(src.zip)、これを展開し、Javadocコメントの@sinceタグに1.7とあるものを抽出すればいいというのが最初の発想です。
JDK 7のソースコードからJavadocコメントの@sinceタグ部分抜粋
新しく導入されたクラスは、クラスのJavadocに記載される@sinceタグに1.7と書かれています。以下は、JDK 7で新規追加されるクラス javax.swing.JLayer の例です。
package javax.swing; :(中略) /** * {@code JLayer} is a universal decorator for Swing components :(中略) * @since 1.7 :(中略) */ public final class JLayer<V extends Component> extends JComponent implements Scrollable, PropertyChangeListener, Accessible {
以下は、java.util.logging.Loggerクラスに、JDK 7で新規追加されるメソッド getGlobal の例です。
/** * Return global logger object with the name Logger.GLOBAL_LOGGER_NAME. * * @return global logger object * @since 1.7 */ public static final Logger getGlobal() { return global; }
@since 1.7が記載されたクラスやメソッドを抽出するには
find, grep, awkでは、ちょっとつらい(同一行にクラス・メソッド情報がないため)ので、いろいろ考えてみましたが、これは自分でJavadocのDoclet実装を書き、@sinceタグで1.7の記述があるクラス・メソッドの名前だけ出力すればよいと思いました。
JavadocのDocletを書いてみる
そこで、見よう見まねで作ってみたのが以下です。
package jp.gr.java_conf.torutk.doclets; import com.sun.javadoc.ClassDoc; import com.sun.javadoc.MethodDoc; import com.sun.javadoc.RootDoc; import com.sun.javadoc.Tag; public class ListBySinceDoclet { private static final String TAG_SINCE = "@since"; public static boolean start(RootDoc root) { ClassDoc[] classDocs = root.classes(); for (ClassDoc classDoc : classDocs) { Tag[] sinceTags = classDoc.tags(TAG_SINCE); if (isSinceTagMatches(sinceTags)) { System.out.println(classDoc.qualifiedName() + " [class]"); } MethodDoc[] methodDocs = classDoc.methods(); for (MethodDoc methodDoc : methodDocs) { if (isSinceTagMatches(methodDoc.tags(TAG_SINCE))) { System.out.println(classDoc.qualifiedName() + "#" + methodDoc.name()); } } } return true; } private static boolean isSinceTagMatches(Tag[] tags) { for (Tag tag : tags) { if ("1.7".equals(tag.text())) { return true; } } return false; } }
自前のJavadocクラスを作るときは、特に継承するものはなく、public staticなstartメソッドを定義すればよいようです。引数に渡されるRootDocオブジェクトから芋づる的にたぐって、クラスやメソッドのJavadocコメントに書かれた@sinceタグを取り出し、値が1.7と一致するか調べ、一致していたらクラス名またはメソッド名をprintしているだけのコードです。
実行
カレントディレクトリをjdk 7のsrc.zip展開場所に移動し、自前のJavadocクラスを置いた場所と自前のJavadocクラス、解析対象パッケージを指定します。
C:\work\jdk7\src> javadoc -docletpath C:\work\since \ -doclet jp.gr.java_conf.torutk.doclets.ListBySinceDoclet \ -subpackages java:javax:org :(中略) java.lang.Byte#compare java.lang.Boolean#compare java.lang.AutoCloseable [class] :(後略)
JDK 7 build 130のsrc.zipに対して実行した結果一覧
java.applet.Applet#isValidateRoot java.awt.Window#setAutoRequestFocus java.awt.Window#isAutoRequestFocus java.awt.Window#isValidateRoot java.awt.Window#setType java.awt.Window#getType java.awt.Window#getOpacity java.awt.Window#setOpacity java.awt.Window#getShape java.awt.Window#setShape java.awt.Window#isOpaque java.awt.Window#paint java.awt.Window.Type [class] java.awt.Toolkit#areExtraMouseButtonsEnabled java.awt.SecondaryLoop [class] java.awt.GraphicsDevice#isWindowTranslucencySupported java.awt.GraphicsDevice.WindowTranslucency [class] java.awt.GraphicsConfiguration#isTranslucencyCapable java.awt.FileDialog#getFiles java.awt.FileDialog#setMultipleMode java.awt.FileDialog#isMultipleMode java.awt.EventQueue#createSecondaryLoop java.awt.Container#isValidateRoot java.awt.event.MouseWheelEvent#getPreciseWheelRotation java.awt.event.KeyEvent#getExtendedKeyCode java.awt.event.KeyEvent#getExtendedKeyCodeForChar java.awt.event.InvocationEvent#isDispatched java.awt.font.NumericShaper#getShaper java.awt.font.NumericShaper#getContextualShaper java.awt.font.NumericShaper#getContextualShaper java.awt.font.NumericShaper#shape java.awt.font.NumericShaper#getRangeSet java.awt.font.NumericShaper.Range [class] .\java\awt\peer\DialogPeer.java:69: 警告 - タグ@see: java.awt.DialogでblockWindows()が見つかりません java.awt.peer.ComponentPeer#applyShape java.awt.peer.ComponentPeer#updateGraphicsData java.awt.peer.CanvasPeer#getAppropriateGraphicsConfiguration java.beans.XMLDecoder#createHandler java.beans.Transient [class] java.beans.PropertyChangeEvent#toString java.beans.Introspector#getBeanInfo java.beans.FeatureDescriptor#toString java.beans.Expression#execute java.io.File#toPath java.lang.Throwable#addSuppressed java.lang.Throwable#getSuppressed java.lang.Short#compare java.lang.ReflectiveOperationException [class] java.lang.ProcessBuilder#redirectInput java.lang.ProcessBuilder#redirectOutput java.lang.ProcessBuilder#redirectError java.lang.ProcessBuilder#redirectInput java.lang.ProcessBuilder#redirectOutput java.lang.ProcessBuilder#redirectError java.lang.ProcessBuilder#redirectInput java.lang.ProcessBuilder#redirectOutput java.lang.ProcessBuilder#redirectError java.lang.ProcessBuilder#inheritIO java.lang.ProcessBuilder.Redirect [class] java.lang.Long#compare java.lang.Integer#compare java.lang.ClassLoader#getClassLoadingLock java.lang.ClassLoader#registerAsParallelCapable java.lang.Character#isBmpCodePoint java.lang.Character#isSurrogate java.lang.Character#highSurrogate java.lang.Character#lowSurrogate java.lang.Character#compare java.lang.Character#getName java.lang.Character.UnicodeScript [class] java.lang.Byte#compare java.lang.Boolean#compare java.lang.AutoCloseable [class] java.lang.management.PlatformManagedObject [class] java.lang.management.ManagementFactory#getPlatformMXBeans java.lang.management.ManagementFactory#getPlatformMXBeans java.lang.management.ManagementFactory#getAllPlatformMXBeanInterfaces java.lang.reflect.Modifier#classModifiers java.lang.reflect.Modifier#interfaceModifiers java.lang.reflect.Modifier#constructorModifiers java.lang.reflect.Modifier#methodModifiers java.lang.reflect.Modifier#fieldModifiers java.net.URLClassLoader#getResourceAsStream java.net.URLClassLoader#close java.net.StandardSocketOption [class] java.net.StandardProtocolFamily [class] java.net.SocketOption [class] java.net.ProtocolFamily [class] java.net.NetworkInterface#getIndex java.net.NetworkInterface#getByIndex java.net.InetSocketAddress#getHostString java.net.InetAddress#getLoopbackAddress java.net.HttpURLConnection#setFixedLengthStreamingMode java.nio.BufferPoolMXBean [class] java.nio.channels.WritePendingException [class] java.nio.channels.SocketChannel#bind java.nio.channels.SocketChannel#setOption java.nio.channels.SocketChannel#shutdownInput java.nio.channels.SocketChannel#shutdownOutput java.nio.channels.SocketChannel#getRemoteAddress java.nio.channels.ShutdownChannelGroupException [class] java.nio.channels.ServerSocketChannel#bind java.nio.channels.ServerSocketChannel#bind java.nio.channels.ServerSocketChannel#setOption java.nio.channels.SeekableByteChannel [class] java.nio.channels.ReadPendingException [class] java.nio.channels.NetworkChannel [class] java.nio.channels.MulticastChannel [class] java.nio.channels.MembershipKey [class] java.nio.channels.InterruptedByTimeoutException [class] java.nio.channels.IllegalChannelGroupException [class] java.nio.channels.FileLock#acquiredBy java.nio.channels.FileLock#close java.nio.channels.FileChannel#open java.nio.channels.FileChannel#open java.nio.channels.DatagramChannel#open java.nio.channels.DatagramChannel#bind java.nio.channels.DatagramChannel#setOption java.nio.channels.DatagramChannel#getRemoteAddress java.nio.channels.CompletionHandler [class] java.nio.channels.Channels#newInputStream java.nio.channels.Channels#newOutputStream java.nio.channels.AsynchronousSocketChannel [class] java.nio.channels.AsynchronousServerSocketChannel [class] java.nio.channels.AsynchronousFileChannel [class] java.nio.channels.AsynchronousChannelGroup [class] java.nio.channels.AsynchronousChannel [class] java.nio.channels.AsynchronousByteChannel [class] java.nio.channels.AlreadyBoundException [class] java.nio.channels.AcceptPendingException [class] java.nio.channels.spi.SelectorProvider#openDatagramChannel java.nio.channels.spi.AsynchronousChannelProvider [class] java.nio.file.Watchable [class] java.nio.file.WatchService [class] java.nio.file.WatchKey [class] java.nio.file.WatchEvent [class] java.nio.file.WatchEvent.Kind [class] java.nio.file.WatchEvent.Modifier [class] java.nio.file.StandardWatchEventKind [class] java.nio.file.StandardOpenOption [class] java.nio.file.StandardCopyOption [class] java.nio.file.SimpleFileVisitor [class] java.nio.file.SecureDirectoryStream [class] java.nio.file.Paths [class] java.nio.file.PathMatcher [class] java.nio.file.Path [class] java.nio.file.OpenOption [class] java.nio.file.NotLinkException [class] java.nio.file.NotDirectoryException [class] java.nio.file.NoSuchFileException [class] java.nio.file.LinkPermission [class] java.nio.file.LinkOption [class] java.nio.file.Files [class] java.nio.file.FileVisitor [class] java.nio.file.FileVisitResult [class] java.nio.file.FileVisitOption [class] java.nio.file.FileSystems [class] java.nio.file.FileSystemLoopException [class] java.nio.file.FileSystemException [class] java.nio.file.FileSystem [class] java.nio.file.FileStore [class] java.nio.file.FileAlreadyExistsException [class] java.nio.file.DirectoryStream [class] java.nio.file.DirectoryStream.Filter [class] java.nio.file.DirectoryNotEmptyException [class] java.nio.file.DirectoryIteratorException [class] java.nio.file.CopyOption [class] java.nio.file.ClosedDirectoryStreamException [class] java.nio.file.AtomicMoveNotSupportedException [class] java.nio.file.AccessMode [class] java.nio.file.AccessDeniedException [class] java.nio.file.attribute.UserPrincipalNotFoundException [class] java.nio.file.attribute.UserPrincipalLookupService [class] java.nio.file.attribute.UserPrincipal [class] java.nio.file.attribute.UserDefinedFileAttributeView [class] java.nio.file.attribute.PosixFilePermissions [class] java.nio.file.attribute.PosixFilePermission [class] java.nio.file.attribute.PosixFileAttributes [class] java.nio.file.attribute.PosixFileAttributeView [class] java.nio.file.attribute.GroupPrincipal [class] java.nio.file.attribute.FileTime [class] java.nio.file.attribute.FileStoreAttributeView [class] java.nio.file.attribute.FileOwnerAttributeView [class] java.nio.file.attribute.FileAttributeView [class] java.nio.file.attribute.FileAttribute [class] java.nio.file.attribute.DosFileAttributes [class] java.nio.file.attribute.DosFileAttributeView [class] java.nio.file.attribute.BasicFileAttributes [class] java.nio.file.attribute.BasicFileAttributeView [class] java.nio.file.attribute.AttributeView [class] java.nio.file.attribute.AclFileAttributeView [class] java.nio.file.attribute.AclEntryType [class] java.nio.file.attribute.AclEntryPermission [class] java.nio.file.attribute.AclEntryFlag [class] java.nio.file.attribute.AclEntry [class] java.nio.file.attribute.AclEntry.Builder [class] java.nio.file.spi.FileTypeDetector [class] java.nio.file.spi.FileSystemProvider [class] java.security.CryptoPrimitive [class] java.security.AlgorithmConstraints [class] java.security.cert.X509CRLEntry#getRevocationReason java.security.cert.PKIXReason [class] java.security.cert.Extension [class] java.security.cert.CertificateRevokedException [class] java.security.cert.CertPathValidatorException#getReason java.security.cert.CertPathValidatorException.Reason [class] java.security.cert.CertPathValidatorException.BasicReason [class] java.security.cert.CRLReason [class] java.sql.Statement#closeOnCompletion java.sql.Statement#isCloseOnCompletion java.sql.ResultSet#getObject java.sql.ResultSet#getObject java.sql.PseudoColumnUsage [class] java.sql.Driver#getParentLogger java.sql.DatabaseMetaData#getPseudoColumns java.sql.DatabaseMetaData#generatedKeyAlwaysReturned java.sql.Connection#setSchema java.sql.Connection#getSchema java.sql.Connection#abort java.sql.Connection#setNetworkTimeout java.sql.Connection#getNetworkTimeout java.sql.CallableStatement#getObject java.sql.CallableStatement#getObject java.util.Objects [class] java.util.Locale#getDefault java.util.Locale#setDefault java.util.Locale#getScript java.util.Locale#getExtension java.util.Locale#getExtensionKeys java.util.Locale#getUnicodeLocaleAttributes java.util.Locale#getUnicodeLocaleType java.util.Locale#getUnicodeLocaleKeys java.util.Locale#toLanguageTag java.util.Locale#forLanguageTag java.util.Locale#getDisplayScript java.util.Locale#getDisplayScript java.util.Locale.Category [class] java.util.Locale.Builder [class] java.util.IllformedLocaleException [class] java.util.GregorianCalendar#isWeekDateSupported java.util.GregorianCalendar#getWeekYear java.util.GregorianCalendar#setWeekDate java.util.GregorianCalendar#getWeeksInWeekYear java.util.Currency#getAvailableCurrencies java.util.Currency#getNumericCode java.util.Currency#getDisplayName java.util.Currency#getDisplayName java.util.Collections#emptyIterator java.util.Collections#emptyListIterator java.util.Collections#emptyEnumeration java.util.Calendar#isWeekDateSupported java.util.Calendar#getWeekYear java.util.Calendar#setWeekDate java.util.Calendar#getWeeksInWeekYear java.util.BitSet#valueOf java.util.BitSet#valueOf java.util.BitSet#valueOf java.util.BitSet#valueOf java.util.BitSet#toByteArray java.util.BitSet#toLongArray java.util.BitSet#previousSetBit java.util.BitSet#previousClearBit java.util.concurrent.TransferQueue [class] java.util.concurrent.ThreadLocalRandom [class] java.util.concurrent.ScheduledThreadPoolExecutor#setRemoveOnCancelPolicy java.util.concurrent.ScheduledThreadPoolExecutor#getRemoveOnCancelPolicy java.util.concurrent.RecursiveTask [class] java.util.concurrent.RecursiveAction [class] java.util.concurrent.Phaser [class] java.util.concurrent.LinkedTransferQueue [class] java.util.concurrent.ForkJoinWorkerThread [class] java.util.concurrent.ForkJoinTask [class] java.util.concurrent.ForkJoinPool [class] java.util.concurrent.ConcurrentLinkedDeque [class] java.util.concurrent.locks.AbstractQueuedSynchronizer#hasQueuedPredecessors java.util.concurrent.locks.AbstractQueuedLongSynchronizer#hasQueuedPredecessors java.util.logging.PlatformLoggingMXBean [class] java.util.logging.Logger#getGlobal java.util.spi.LocaleNameProvider#getDisplayScript java.util.spi.CurrencyNameProvider#getDisplayName java.util.zip.DeflaterOutputStream#flush java.util.zip.Deflater#deflate javax.lang.model.element.QualifiedNameable [class] javax.lang.model.element.Parameterizable [class] javax.lang.model.UnknownEntityException [class] javax.lang.model.type.TypeVisitor#visitDisjunctive javax.lang.model.type.DisjunctiveType [class] javax.lang.model.util.TypeKindVisitor7 [class] javax.lang.model.util.SimpleTypeVisitor7 [class] javax.lang.model.util.SimpleElementVisitor7 [class] javax.lang.model.util.SimpleAnnotationValueVisitor7 [class] javax.lang.model.util.ElementScanner7 [class] javax.lang.model.util.ElementKindVisitor7 [class] javax.lang.model.util.ElementKindVisitor6#visitVariableAsResourceVariable javax.lang.model.util.AbstractTypeVisitor7 [class] javax.lang.model.util.AbstractTypeVisitor6#visitDisjunctive javax.lang.model.util.AbstractElementVisitor7 [class] javax.lang.model.util.AbstractAnnotationValueVisitor7 [class] javax.print.attribute.standard.DialogTypeSelection [class] javax.sound.midi.MidiDeviceTransmitter [class] javax.sound.midi.MidiDeviceReceiver [class] javax.sql.CommonDataSource#getParentLogger javax.sql.rowset.RowSetProvider [class] javax.sql.rowset.RowSetProvider#newFactory javax.sql.rowset.RowSetProvider#newFactory javax.sql.rowset.RowSetFactory [class] javax.sql.rowset.RowSetFactory#createCachedRowSet javax.sql.rowset.RowSetFactory#createFilteredRowSet javax.sql.rowset.RowSetFactory#createJdbcRowSet javax.sql.rowset.RowSetFactory#createJoinRowSet javax.sql.rowset.RowSetFactory#createWebRowSet javax.swing.SwingUtilities#getUnwrappedParent javax.swing.SwingUtilities#getUnwrappedView javax.swing.JTree.EmptySelectionModel#setSelectionMode javax.swing.JTree.EmptySelectionModel#setRowMapper javax.swing.JTree.EmptySelectionModel#addTreeSelectionListener javax.swing.JTree.EmptySelectionModel#removeTreeSelectionListener javax.swing.JTree.EmptySelectionModel#addPropertyChangeListener javax.swing.JTree.EmptySelectionModel#removePropertyChangeListener javax.swing.JSlider#imageUpdate javax.swing.JList#getSelectedValuesList javax.swing.JLayer [class] javax.swing.BorderFactory#createLineBorder javax.swing.BorderFactory#createRaisedSoftBevelBorder javax.swing.BorderFactory#createLoweredSoftBevelBorder javax.swing.BorderFactory#createSoftBevelBorder javax.swing.BorderFactory#createSoftBevelBorder javax.swing.BorderFactory#createSoftBevelBorder javax.swing.BorderFactory#createStrokeBorder javax.swing.BorderFactory#createStrokeBorder javax.swing.BorderFactory#createDashedBorder javax.swing.BorderFactory#createDashedBorder javax.swing.BorderFactory#createDashedBorder javax.swing.border.StrokeBorder [class] javax.swing.event.HyperlinkEvent#getInputEvent javax.swing.plaf.LayerUI [class] javax.swing.plaf.FileChooserUI#getDefaultButton javax.swing.plaf.basic.BasicTreeUI#isDropLine javax.swing.plaf.basic.BasicTreeUI#paintDropLine javax.swing.plaf.basic.BasicTreeUI#getDropLineRect javax.swing.plaf.basic.BasicTreeUI#updateLeadSelectionRow javax.swing.plaf.basic.BasicTreeUI#getLeadSelectionRow javax.swing.plaf.basic.BasicFileChooserUI#createUI javax.swing.plaf.basic.BasicComboBoxUI#getSizeForComponent javax.swing.plaf.basic.BasicColorChooserUI#uninstallPreviewPanel javax.swing.plaf.nimbus.NimbusLookAndFeel#shouldUpdateStyleOnEvent javax.swing.plaf.synth.SynthViewportUI [class] javax.swing.plaf.synth.SynthUI [class] javax.swing.plaf.synth.SynthTreeUI [class] javax.swing.plaf.synth.SynthToolTipUI [class] javax.swing.plaf.synth.SynthToolBarUI [class] javax.swing.plaf.synth.SynthToggleButtonUI [class] javax.swing.plaf.synth.SynthTextPaneUI [class] javax.swing.plaf.synth.SynthTextFieldUI [class] javax.swing.plaf.synth.SynthTextAreaUI [class] javax.swing.plaf.synth.SynthTableUI [class] javax.swing.plaf.synth.SynthTableHeaderUI [class] javax.swing.plaf.synth.SynthTabbedPaneUI [class] javax.swing.plaf.synth.SynthSplitPaneUI [class] javax.swing.plaf.synth.SynthSpinnerUI [class] javax.swing.plaf.synth.SynthSliderUI [class] javax.swing.plaf.synth.SynthSeparatorUI [class] javax.swing.plaf.synth.SynthScrollPaneUI [class] javax.swing.plaf.synth.SynthScrollBarUI [class] javax.swing.plaf.synth.SynthRootPaneUI [class] javax.swing.plaf.synth.SynthRadioButtonUI [class] javax.swing.plaf.synth.SynthRadioButtonMenuItemUI [class] javax.swing.plaf.synth.SynthProgressBarUI [class] javax.swing.plaf.synth.SynthPopupMenuUI [class] javax.swing.plaf.synth.SynthPasswordFieldUI [class] javax.swing.plaf.synth.SynthPanelUI [class] javax.swing.plaf.synth.SynthOptionPaneUI [class] javax.swing.plaf.synth.SynthMenuUI [class] javax.swing.plaf.synth.SynthMenuItemUI [class] javax.swing.plaf.synth.SynthMenuBarUI [class] javax.swing.plaf.synth.SynthLookAndFeel#shouldUpdateStyleOnEvent javax.swing.plaf.synth.SynthListUI [class] javax.swing.plaf.synth.SynthLabelUI [class] javax.swing.plaf.synth.SynthInternalFrameUI [class] javax.swing.plaf.synth.SynthFormattedTextFieldUI [class] javax.swing.plaf.synth.SynthEditorPaneUI [class] javax.swing.plaf.synth.SynthDesktopPaneUI [class] javax.swing.plaf.synth.SynthDesktopIconUI [class] javax.swing.plaf.synth.SynthComboBoxUI [class] javax.swing.plaf.synth.SynthColorChooserUI [class] javax.swing.plaf.synth.SynthCheckBoxUI [class] javax.swing.plaf.synth.SynthCheckBoxMenuItemUI [class] javax.swing.plaf.synth.SynthButtonUI [class] javax.swing.text.JTextComponent#saveComposedText javax.swing.text.JTextComponent#restoreComposedText javax.swing.text.DefaultStyledDocument#removeElement javax.swing.tree.DefaultTreeCellRenderer#updateUI