Захотелось получить статистику Java исходников и узнать, сколько в среднем бывает параметров у методов, методов в классах, конструкторов и т. д. Вопрос не совсем праздный, потому что на основе этих данных можно вычислить оптимальный размер по умолчанию для контейнеров для этих сущностей в программной модели кода (AST), чтобы сэкономить память. В частности, речь идет о проекте Spoon. С помощью этой библиотеки я и провел анализ, кстати.

Что может быть логичнее, чем протестировать статистику исходников JDK, чтобы делать некие предположения о любом Java-коде. Попутно я собрал самые необычные экземпляры — например, методы с наибольшим кол-вом параметров.

Чтобы посмотреть на них, гуглите сигнатуру — первая ссылка должна быть на Javadoc или на GrepCode. Либо, если перед вами открыта IntelliJ IDEA, просто вставьте имя класса или метода после четверного нажатия Shift.

Я ограничился только пакетами java.*, javax.* и org.*, а также JDK 7, а не 8, потому что баги Eclipse-компилятора, на котором основан Spoon, не позволяют построить AST.

С точки зрения статистики — я считаю хорошим допущением, что количества всех рассматриваемых сущностей распределены по закону Пуассона, поэтому единственное число — среднее значение — неплохо описывает все распределение.

Но, при желании, вы можете провести более глубокий анализ, или протестировать свой проект: gist.github.com/leventov/1f8d8d470b9632bc3cc3

Параметры методов


Среднее: 1,063

Кол-во Метод
12 java.lang.String layoutCompoundLabel(javax.swing.JComponent,java.awt.FontMetrics,java.lang.String,javax.swing.Icon,int,int,int,int,java.awt.Rectangle,java.awt.Rectangle,java.awt.Rectangle,int)
12 void drawChunk(java.awt.Image,java.awt.Graphics,boolean,int,int,int,int,int,int,int,int,boolean)
12 java.lang.String layoutText(javax.swing.plaf.synth.SynthContext,java.awt.FontMetrics,java.lang.String,javax.swing.Icon,int,int,int,int,java.awt.Rectangle,java.awt.Rectangle,java.awt.Rectangle,int)
14 void paintRow(javax.swing.tree.TreeCellRenderer,javax.swing.tree.DefaultTreeCellRenderer,javax.swing.plaf.synth.SynthContext,javax.swing.plaf.synth.SynthContext,java.awt.Graphics,java.awt.Rectangle,java.awt.Insets,java.awt.Rectangle,java.awt.Rectangle,javax.swing.tree.TreePath,int,boolean,boolean,boolean)
15 void initMouseEvent(java.lang.String,boolean,boolean,org.w3c.dom.views.AbstractView,int,int,int,int,int,boolean,boolean,boolean,boolean,short,org.w3c.dom.events.EventTarget)
16 void setRaster(int,int,int,int,int,int,int,int,int,int,int,int,int,int,int,int)


Типовые параметры методов


Среднее: 0,010

Кол-во метод
2 <K,V> java.util.Map checkedMap(java.util.Map,java.lang.Class,java.lang.Class)
2 <K,V> K keyOrNull(java.util.TreeMap$Entry)
2 <K,V> java.util.concurrent.ConcurrentHashMap$HashEntry entryAt(java.util.concurrent.ConcurrentHashMap$HashEntry[],int)
2 <U,W> java.util.concurrent.atomic.AtomicReferenceFieldUpdater newUpdater(java.lang.Class,java.lang.Class,java.lang.String)
2 <K,V> java.util.Map newHashMap()
2 <M,I> javax.swing.RowFilter andFilter(java.lang.Iterable)
2 <R,P> R accept(javax.lang.model.element.AnnotationValueVisitor,P)
2 <R,P> R accept(javax.lang.model.element.ElementVisitor,P)
2 <R,P> R accept(javax.lang.model.type.TypeVisitor,P)
3 <K,V,T> java.util.Collections$CheckedMap$CheckedEntrySet$CheckedEntry checkedEntry(java.util.Map$Entry,java.lang.Class)


Параметры конструкторов


Среднее: 1,207

Кол-во Конструктор
12 java.awt.LinearGradientPaintContext(java.awt.LinearGradientPaint,java.awt.image.ColorModel,java.awt.Rectangle,java.awt.geom.Rectangle2D,java.awt.geom.AffineTransform,java.awt.RenderingHints,java.awt.geom.Point2D,java.awt.geom.Point2D,float[],java.awt.Color[],java.awt.MultipleGradientPaint$CycleMethod,java.awt.MultipleGradientPaint$ColorSpaceType)
12 java.lang.management.ThreadInfo(java.lang.Thread,int,java.lang.Object,java.lang.Thread,long,long,long,long,java.lang.StackTraceElement[],java.lang.Object[],int[],java.lang.Object[])
12 javax.swing.event.MenuDragMouseEvent(java.awt.Component,int,long,int,int,int,int,int,int,boolean,javax.swing.MenuElement[],javax.swing.MenuSelectionManager)
13 java.awt.event.MouseWheelEvent(java.awt.Component,int,long,int,int,int,int,int,int,boolean,int,int,int)
13 java.util.SimpleTimeZone(int,java.lang.String,int,int,int,int,int,int,int,int,int,int,int)
14 java.awt.event.MouseWheelEvent(java.awt.Component,int,long,int,int,int,int,int,int,boolean,int,int,int,double)
15 java.awt.RadialGradientPaintContext(java.awt.RadialGradientPaint,java.awt.image.ColorModel,java.awt.Rectangle,java.awt.geom.Rectangle2D,java.awt.geom.AffineTransform,java.awt.RenderingHints,float,float,float,float,float,float[],java.awt.Color[],java.awt.MultipleGradientPaint$CycleMethod,java.awt.MultipleGradientPaint$ColorSpaceType)
16 javax.imageio.spi.ImageReaderWriterSpi(java.lang.String,java.lang.String,java.lang.String[],java.lang.String[],java.lang.String[],java.lang.String,boolean,java.lang.String,java.lang.String,java.lang.String[],java.lang.String[],boolean,java.lang.String,java.lang.String,java.lang.String[],java.lang.String[])
18 javax.imageio.spi.ImageReaderSpi(java.lang.String,java.lang.String,java.lang.String[],java.lang.String[],java.lang.String[],java.lang.String,java.lang.Class[],java.lang.String[],boolean,java.lang.String,java.lang.String,java.lang.String[],java.lang.String[],boolean,java.lang.String,java.lang.String,java.lang.String[],java.lang.String[])
18 javax.imageio.spi.ImageWriterSpi(java.lang.String,java.lang.String,java.lang.String[],java.lang.String[],java.lang.String[],java.lang.String,java.lang.Class[],java.lang.String[],boolean,java.lang.String,java.lang.String,java.lang.String[],java.lang.String[],boolean,java.lang.String,java.lang.String,java.lang.String[],java.lang.String[])

Типовые параметры конструкторов


Среднее: 0,001

Многие даже не знают, что так бывает. В JDK нашлось аж четыре класса с параметризованными конструкторами. Хотя мне доводилось примерять эту фишку на практике, причем, кажется, даже не единожды.
Кол-во Конструктор
1 javax.management.StandardEmitterMBean(T,java.lang.Class,boolean,javax.management.NotificationEmitter)
1 javax.management.StandardMBean(T,java.lang.Class)
1 javax.management.openmbean.OpenMBeanAttributeInfoSupport(java.lang.String,java.lang.String,javax.management.openmbean.OpenType,boolean,boolean,boolean,T)
1 javax.management.openmbean.OpenMBeanParameterInfoSupport(java.lang.String,java.lang.String,javax.management.openmbean.OpenType,T)


Типовые параметры классов


Среднее: 0,117

Неожиданно не нашлось ни одного класса с более чем тремя типовыми параметрами. Мой личный рекорд — 8.
Кол-во Класс
2 class javax.swing.DefaultRowSorter
2 class javax.swing.DefaultRowSorter$ModelWrapper
2 class javax.swing.RowFilter
2 class javax.swing.RowFilter$AndFilter
2 class javax.swing.RowFilter$Entry
2 class javax.swing.RowFilter$NotFilter
2 class javax.swing.RowFilter$OrFilter
2 class javax.swing.SwingWorker
2 class javax.xml.bind.annotation.adapters.XmlAdapter
3 class java.util.Collections$CheckedMap$CheckedEntrySet$CheckedEntry

Реализованные интерфейсы


Среднее: 0,555

Кол-во Класс
6 class javax.swing.plaf.basic.BasicComboBoxUI$Handler
6 class javax.swing.plaf.basic.BasicTabbedPaneUI$Handler
6 class javax.swing.plaf.basic.BasicTableUI$Handler
6 class javax.swing.text.JTextComponent$AccessibleJTextComponent
7 class javax.swing.JTable
7 class javax.swing.JTable$AccessibleJTable
7 class javax.swing.plaf.basic.BasicInternalFrameUI$Handler
7 class javax.swing.plaf.basic.BasicListUI$Handler
10 class javax.swing.plaf.basic.BasicTreeUI$Handler
17 class java.awt.AWTEventMulticaster

Анонимные блоки инициализации


Среднее: 0,057

Тут, наоборот, авторы JDK любят блоки инициализации больше меня. Я никогда не писал больше одного блока на класс.
Кол-во Класс
2 class javax.management.remote.rmi.RMIConnector
2 class javax.swing.text.html.HTML
3 class java.lang.invoke.CallSite
3 class java.lang.invoke.MethodHandle
3 class java.lang.invoke.MethodHandleNatives
3 class java.math.BigInteger
3 class java.net.InetAddress
3 class java.util.zip.ZipFile
3 class javax.swing.text.rtf.RTFReader
6 class java.lang.invoke.LambdaForm

Поля


Среднее: 3,861

Кол-во Класс
84 class java.awt.Event
84 class java.util.Calendar
93 class javax.swing.plaf.nimbus.InternalFrameTitlePaneMaximizeButtonPainter
98 class java.awt.Component
99 enum java.lang.Character$UnicodeScript
130 class java.awt.color.ICC_Profile
140 class javax.swing.plaf.nimbus.FileChooserPainter
209 class java.awt.event.KeyEvent
213 class java.lang.Character$UnicodeBlock
223 class java.awt.PageAttributes$MediaType

Конструкторы


Среднее: 1,467

Кол-во Класс
10 class java.lang.invoke.MemberName
10 class java.net.Socket
10 class java.sql.BatchUpdateException
12 class java.math.BigInteger
13 class java.util.Scanner
14 class java.awt.Dialog
16 class java.util.Formatter
16 class javax.swing.JDialog
17 class java.lang.String
17 class java.math.BigDecimal

Методы


Среднее: 8,003

Кол-во Класс
137 class javax.swing.plaf.synth.ParsedSynthStyle$DelegatingPainter
143 class javax.swing.plaf.nimbus.SynthPainterImpl
143 class javax.swing.plaf.synth.ImagePainter
145 class java.awt.Window
147 class javax.swing.JTree
148 class javax.swing.plaf.nimbus.FileChooserPainter
152 class java.awt.Container
187 class javax.swing.JComponent
196 class javax.swing.JTable
331 class java.awt.Component

Вложенные классы


Среднее: 0,327

Кол-во Класс
20 class javax.swing.plaf.metal.MetalBorders
20 class javax.swing.text.html.CSS
21 class javax.swing.plaf.basic.BasicTreeUI
21 class javax.swing.text.html.HTMLDocument$HTMLReader
27 class java.beans.MetaData$java_util_Collections
30 class javax.swing.plaf.metal.MetalIconFactory
33 class javax.swing.text.DefaultEditorKit
36 class java.util.Collections
48 class java.beans.MetaData
59 class java.util.regex.Pattern

Комментарии (12)


  1. lany
    24.05.2015 20:17
    +1

    Отдельный плюс за генерик-параметры конструктора :-) В восьмёрке генерик параметров в целом стало существенно больше. Вон, навскидку java.util.stream.AbstractTask<P_IN, P_OUT, R, K> — четыре параметра, и среди его наследников ещё с полдюжины таких. А какой-нибудь java.util.stream.Collectors.groupingBy(Function<? super T, ? extends K>, Supplier<M>, Collector<? super T, A, D>) имеет целых пять генерик-параметров.


    1. leventov Автор
      24.05.2015 20:48

      Ага, по поводу последнего любят твитить в стиле «вы можете понять сигнатуру этого метода? Java превратилась в адЪ»


      1. lany
        24.05.2015 20:57
        +1

        А я как-то привык уже. Сам пишу в таком духе :-) Вон меня на SO сам Stuart Marks плюсанул за 6 генерик-параметров. По факту в какой-то момент щёлкает в голове, и потом уже это не выглядит сложно.


      1. Nagg
        25.05.2015 00:07

        Аналог этого в C# тоже по сигнатуре выглядет страшно :)

        IEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, Func<TKey, IEnumerable<TElement>, TResult> resultSelector, IEqualityComparer<TKey> comparer)


  1. lany
    24.05.2015 20:22
    +1

    Поля, конечно, стоило поделить на статичные и нестатичные. Одно дело, когда класс типа java.awt.PageAttributes.MediaType, который просто набор констант, а другое — действительно адский по числу полей javax.swing.plaf.nimbus.FileChooserPainter.


  1. QtRoS
    24.05.2015 20:30
    -1

    О чем думали люди, которые делали конструктор с 18-ю параметрами…
    java.awt.Event с 80+ полей тоже порадовал, на каких же там костылях все работает, и с чем же боролись эти парни, ведь рекордсмен по интерфейсам java.awt.AWTEventMulticaster тоже с событиями связан!


    1. lany
      24.05.2015 20:58
      +1

      Это внутренние детали реализации. Для них важно быть не столько красивыми, сколько быстрыми. Вообще-то куски Java и на ассемблере написаны, это тоже не очень красиво кому-то покажется =)


      1. QtRoS
        25.05.2015 09:38
        -1

        Не соглашусь. Практика показывает, что если в чем-то не смогли разобраться как следует, то происходит неоправданное усложнение. Я думаю, что это именно тот случай и соглашусь с комментарием vsb ниже.


    1. lany
      25.05.2015 09:09

      Ну и, кстати, в java.awt.Event всего 12 полей. Остальное — статические константы, описывающие типы событий. Из 12 полей большинство выглядит разумными. Косяк только в том, что они по большей части публичные и не финальные.


  1. vsb
    24.05.2015 23:57
    -1

    Да, уж, Swing и AWT почти везде отличились. Всё же не место им в стандартной библиотеке. Были бы отдельными библиотеками — глядишь, Java GUI был бы в лучшем состоянии. А так вроде и стандарт есть, но какой-то он не сильно качественный, этот стандарт.


    1. lany
      25.05.2015 05:57

      В Java-9 в рамках проекта JigSaw вынесли весь Swing/AWT в отдельный модуль java.desktop. Насколько я понимаю идею, должна быть возможность собрать кастомизированный JDK без этого модуля. Сам не пробовал :-) RMI, SQL, w3c DOM тоже в отдельных модулях.


  1. Maccimo
    25.05.2015 13:26
    +1

    Такое впечатление, что в «типовых параметрах методов» чего-то не хватает.
    Декларация generic-параметров есть, а использования не видно. Да и пробелы после запятых не помешали бы.

    Возможно, SWING и AWT стоило исключить из анализа? Они сильно зашумляют результаты.