Я пытаюсь найти размер файла, используя оператор -s
. Это выглядит так:
my $filesz = -s $filename
Я пробовал много разных способов, но он не может получить этот размер.
Чтобы получить разъяснения по этому вопросу, чтобы его можно было вновь открыть, посетите справочный центр .
Какой лучший и самый чистый способ сделать это? В частности, мне нужен некоторый код в блоке статического инициализатора для запуска в этом классе, но я бы хотел сделать его максимально чистым.
Загрузка! = Инициализация.
Вы хотите, чтобы ваш класс был инициализирован (это, помимо прочего, когда выполняются статические блоки).
В отрывке из Спецификации языка Java говорится:
Класс или тип интерфейса T будет инициализирован непосредственно перед первым появлением> любого из следующих значений:
- T - это класс и создается экземпляр T.
- T - это класс, и вызывается статический метод, объявленный T.
- Назначено статическое поле, объявленное T.
- Используется статическое поле, объявленное T, и поле не является постоянной переменной (§4.12.4).
- T - это класс верхнего уровня, и выполняется оператор assert (§14.10), лексически вложенный в T.
Вызов определенных отражающих методов в классе Class и в пакете java.lang.reflect также вызывает инициализацию класса или интерфейса. Класс или интерфейс не будут инициализированы ни при каких других обстоятельствах.
Doh, anovstrup, уже сказал это: просто создайте пустую статическую функцию с именем init
. Убедитесь, что это хорошо задокументировано ... Я лично не вижу никакого варианта использования этого в контексте хорошо сформированного кода.
Одним из решений может быть вызов статического метода:
public class A {
static { DebugUtils.FLAG_TEST_USER = true; }
static void init() {}
}
Затем вызовите A.init ()
для принудительной инициализации.
Однако делать это вообще - это запах кода. Рассмотрите возможность замены статического кода на стандартный конструктор в одноэлементном объекте.
try
{
Class.forName(class name as string)
}
catch(ClassNotFoundException e)
{
whatever
}
Это должно сработать.
@Longpoke
Может, я что-то неправильно понимаю. Можете ли вы создать пример, в котором класс загружается, но статический инициализатор , а не выполняется? Вот пример, который ничего не делает, кроме распечатки того, что он загружен:
package test;
public class TestStatic
{
public static void main(String[] args)
{
try
{
Class.forName("test.Static");
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
}
}
При загрузке следующего статического класса:
package test;
public class Static
{
static
{
System.out.println("Static Initializer ran...");
}
}
Если статические инициализаторы не запускаются до тех пор, пока не будут выполнены перечисленные вами условия, то почему этот println запускается когда я запускаю свой тест? Какое из перечисленных вами условий я выполняю?
Невидимые зависимости между классами — плохая идея. Я предлагаю переместить код из статического блока инициализатора в статический метод и вызвать его непосредственно в зависимом классе. Блок статического инициализатора можно переписать для вызова вновь созданного статического метода.
Если вам нужно статически инициализировать что-то в классе, это означает, что от этого должны зависеть клиентские классы.
Если есть один клиент, или назовем его естественным домом для блока инициализации, я думаю, было бы чище инициализировать его там.
В случае множества равных клиентов может быть хорошей идеей проверить по этим классам, что статическая инициализация в другом классе прошла успешно. Затем связь документируется, и вы уверены, что класс всегда инициализируется до того, как он понадобится первому клиенту.