Предупреждение о попытке с ресурсами для закрытия Super OutputStream

Нижний код компилирует входную строку и возвращает результат в виде целого числа. Хотя это работает, я получаю предупреждение Netbeans о том, что строка super.close() в методе close() класса NewOutputStream должна обрабатываться с помощью try-with-resources. Изменение на:

try (super) {
    this.linkedHashMap.put(this.string,this.byteArrayOutputStream.toByteArray());
}

не работает. Этот вопрос также может быть связан с попробуйте-с-ресурсами-при вызове-супер-конструктора, но я не знаю, как адаптировать ответ к моему коду.

Вот мой код:

package group.javacompiler;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import javax.tools.FileObject;
import javax.tools.ForwardingJavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.JavaFileObject.Kind;
import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;

public class JavaCompiler {

    public static void main(String[] args) {
        try {
            String input = "1+2";
            String returnType = "int";

            String methodName = "methodName";
            String className = "ClassName";
            ArrayList<JavaFileObject> arrayList = new ArrayList<>();
            arrayList.add(new NewCharContent(className+".java",
                "public class "+className+" {\n"+
                "    public static "+returnType+" "+methodName+"() {\n"+
                "       return "+input+";\n"+
                "    }\n"+
                "}"
            ));
            LinkedHashMap<String,byte[]> linkedHashMap = new LinkedHashMap<>();
            javax.tools.JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
            compiler.getTask(null,new NewForwardingJavaFileManager(compiler.getStandardFileManager(null,null,null),linkedHashMap),null,null,null,arrayList).call();

            int result = (int) new NewClassLoader(linkedHashMap).findClass(className).getMethod(methodName).invoke(null,new Object[]{});
            System.out.println(result);
        }
        catch (Throwable throwable) {
            System.out.println(throwable.getMessage());
        }
    }
    private static class NewCharContent extends SimpleJavaFileObject {
        
        private final String charSequence;
        
        private NewCharContent(String string,String charSequence) {
            super(URI.create("string:///"+string),Kind.SOURCE);
            this.charSequence = charSequence;
        }
        
        @Override
        public CharSequence getCharContent(boolean bool) {
            return this.charSequence;
        }
        
    }

    private static class NewForwardingJavaFileManager extends ForwardingJavaFileManager<StandardJavaFileManager> {

        private final LinkedHashMap<String,byte[]> linkedHashMap;

        private NewForwardingJavaFileManager(StandardJavaFileManager fileManager,LinkedHashMap<String,byte[]> linkedHashMap) {
            super(fileManager);
            this.linkedHashMap = linkedHashMap;
        }

        @Override
        public JavaFileObject getJavaFileForOutput(final Location location,final String string,Kind kind,FileObject fileOject) {
            return new NewJavaFileForOutput(string,this.linkedHashMap);
        }

    }

    private static class NewJavaFileForOutput extends SimpleJavaFileObject {

        private final String string;
        private final LinkedHashMap<String,byte[]> linkedHashMap;

        private NewJavaFileForOutput(String string,LinkedHashMap<String,byte[]> linkedHashMap) {
            super(URI.create("string:///"+string+".class"),Kind.CLASS);
            this.string = string;
            this.linkedHashMap = linkedHashMap;
        }

        @Override
        public OutputStream openOutputStream() {
            return new NewOutputStream(this.string,this.linkedHashMap);
        }

    }

    private static class NewOutputStream extends OutputStream {

        private final String string;
        private final LinkedHashMap<String,byte[]> linkedHashMap;
        private final ByteArrayOutputStream byteArrayOutputStream;

        private NewOutputStream(String string,LinkedHashMap<String,byte[]> linkedHashMap) {
            this.string = string;
            this.linkedHashMap = linkedHashMap;
            this.byteArrayOutputStream = new ByteArrayOutputStream();
        }

        @Override
        public void write(int intValue) {
            this.byteArrayOutputStream.write(intValue);
        }

        @Override
        public void close() throws IOException {
            this.linkedHashMap.put(this.string,this.byteArrayOutputStream.toByteArray());
            super.close();
        }

    }

    private static class NewClassLoader extends ClassLoader {

        private final LinkedHashMap<String,byte[]> linkedHashMap;

        private NewClassLoader(LinkedHashMap<String,byte[]> linkedHashMap) {
            this.linkedHashMap = linkedHashMap;
        }

        @Override
        public Class<?> findClass(String string) {
            byte[] byteArray = this.linkedHashMap.get(string);
            return defineClass(string,byteArray,0,byteArray.length);
        }

    }

}

Я бы удалила super.close(). OutputStream — это абстрактный класс, и в любом случае нет никаких родительских ресурсов, поддерживающих ваш заказ OutputStream для закрытия.

Elliott Frisch 16.07.2024 12:14
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
1
70
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Как уже упоминалось, суперреализация, как известно, ничего не делает, но проблема в том, что super.close() не обязательно вызывается. Достаточно простой попытки-наконец.

    @Override
    public void close() throws IOException {
        try {
            linkedHashMap.put(string,
                    byteArrayOutputStream.toByteArray());
        } finally {
            super.close();
        }
    }

На самом деле попытка с ресурсами должна была быть выполнена следующим образом:

try (NewOutputStream nos = new NewOutputStream(this.string,this.linkedHashMap)) {
    ...
}

Это обеспечивает закрытие.

Вам придется сделать некоторые вещи по-другому, но я рад видеть усовершенствованный код, связанный с компилятором.

Здесь я бы рассмотрел более простые (более решаемые напрямую) проблемы стиля кодирования.

  • Программирование с использованием интерфейсов (для более общего кода):

      List<String> string = new ArrayList<>();
    

В дополнение к ответу Джупа Эггена вы можете использовать ссылку на метод в качестве ресурса для закрытия:

    @Override
    public void close() throws IOException {
        try (Closeable _ = super::close) {
            linkedHashMap.put(string,
                    byteArrayOutputStream.toByteArray());
        }
    }

Это будет работать только с Closeable, и если ваш метод имеет объявления, он может выбросить IOException. При использовании с AutoCloseable компилятор сообщит, что вам нужно перехватить или повторно бросить Exception. Если super.close() не объявляет никаких исключений, это также не сработает.

Другие вопросы по теме