Мы создаем веб-проект (Java) с Eclipse. По умолчанию Eclipse использует кодировку Cp1252
на машинах с Windows (которые мы используем).
Поскольку у нас также есть разработчики в Китае (помимо Европы), я начал задаваться вопросом, действительно ли это кодировка, которую нужно использовать .
Моей первоначальной мыслью было преобразовать в UTF-8
, потому что "поддерживает все наборы символов" . Однако действительно ли это мудро? Может, лучше выбрать другую кодировку? Я вижу пару проблем:
1) Как веб-браузер интерпретирует файлы по умолчанию? Зависит ли это от используемой языковой версии? Я хочу, чтобы мы подробно объявляли используемые схемы кодирования:
Xml version = '1.0' encoding = 'UTF-8'?>
объявлений. @CHARSET "UTF-8";
.
или
На самом деле это возможно, но зависит от того, что вы передаете в этот метод. Предположим, у вас есть сценарий, в котором вы передаете метод экземпляра класса, в котором находитесь, в ProcessCommand
:
public class TestClass
{
public void TestMethod()
{
ProcessCommand(() => MethodToCall());
}
public bool MethodToCall() { return true; }
void ProcessCommand(Expression<Func<bool>> expression) { ... }
}
Затем вы можете использовать следующий метод ProcessCommand
. Это работает только потому, что для этого экземпляра вызывается MethodToCall
.
void ProcessCommand(Expression<Func<bool>> expression)
{
var lambda = (LambdaExpression) expression;
var methodCall = (MethodCallExpression) lambda.Body;
var constant = (ConstantExpression) methodCall.Object;
var myObject = constant.Value;
}
Более сложный сценарий выглядит следующим образом:
public class CallingClass
{
public void TestMethod()
{
var calledClass = new CalledClass();
ProcessCommand(() => calledClass.MethodToCall());
}
void ProcessCommand(Expression<Func<bool>> expression) { ... }
}
public class CalledClass
{
public bool MethodToCall() { return true; }
}
Метод, который мы вызываем, теперь находится в другом классе и вызывается не в этом экземпляре, а в экземпляре CalledClass
, называемом calledClass
. Но как компилятор передает переменную namedClass
в лямбда-выражение? Нет ничего, что бы определяло поле namedClass
, для которого может быть вызван метод MethodToCall
.
Компилятор решает эту проблему, создавая внутренний класс с одним полем с именем namedClass
. В результате метод ProcessCommand
теперь выглядит следующим образом:
public void ProcessCommand(Expression<Func<bool>> expression)
{
// The expression is a lambda expression with a method call body.
var lambda = (LambdaExpression) expression;
var methodCall = (MethodCallExpression) lambda.Body;
// The method is called on a member of some instance.
var member = (MemberExpression) methodCall.Object;
// The member expression contains an instance of the anonymous class that
// defines the member...
var constant = (ConstantExpression) member.Expression;
var anonymousClassInstance = constant.Value;
// ...and the member itself.
var calledClassField = (FieldInfo) member.Member;
// With an instance of the anonymous class and the field, we can get its value.
var calledClass =
(CalledClass) calledClassField.GetValue(anonymousClassInstance);
}
Немного сложнее, поскольку компилятору приходится генерировать анонимный внутренний класс.
Это невозможно "из коробки", вы можете взломать что-то с отражением, но это не рекомендуется, это будет очень отсталым.
Редактировать: На самом деле возможно, если верить Рональду, но все же совсем наоборот. Подобные скрытые побочные эффекты затрудняют чтение и сопровождение кода.
Вместо этого ваша ProcessCommand должна принимать либо весь объект aClass
, либо, что предпочтительнее, интерфейс IMyCommand
с .Method()
и дополнительными методами и свойствами, которые ProcessCommand
. Тогда тип aClass.GetType()
должен реализовать IMyCommand
.